This following lines of code is power shell script which allows you to deploy webjob in a web app . The parameters are passed through the settings file reference ...
#Requires -Version 3.0
Param(
[string] $settingsFileName = '\Settings\settings.json',
[boolean] $unitTestMode = $false
)
$Apiversion = "2015-08-01"
# Define FUNCTIONS
#Check if any requirement is missing
function Test-ParameterSet
{
param
(
[parameter(Mandatory = $true)][System.Object]$settings
)
# Loop through the $settings and check no missing setting
if ($null -eq $applicationFileJson.subscriptions) {throw "Missing subscriptions field in settings file"}
foreach ($subscription in $applicationFileJson.subscriptions)
{
if ($null -eq $subscription.subscriptionId) {throw "Missing subscription Id field in settings file"}
# Loop through the $settings and check no missing setting
foreach ($vault in $settings.WorkLoads)
{
if ($null -eq $vault.applicationName) {throw "Missing applicationNam in settings file for $($subscription.subscriptionId)"}
if ($null -eq $vault.environmentName) {throw "Missing environmentName in settings file for $($subscription.subscriptionId)"}
if ($null -eq $vault.resourceGroupName) {throw "Missing resourceGroupName in settings file for $($subscription.subscriptionId)"}
if ($null -eq $vault.webAppName) {throw "Missing webAppName in settings file for $($subscription.subscriptionId)"}
if ($null -eq $vault.Storagerg) {throw "Missing Storagerg in settings file for $($subscription.subscriptionId)"}
if ($null -eq $vault.webjobname) {throw "Missing webjobname in settings file for $($subscription.subscriptionId)"}
if ($null -eq $vault.webjobtype) {throw "Missing webjobtype in settings file for $($subscription.subscriptionId)"}
if ($null -eq $vault.storageAccountName) {throw "Missing storageAccountName in settings file for $($subscription.subscriptionId)"}
if ($null -eq $vault.container_name) {throw "Missing container_name in settings file for $($subscription.subscriptionId)"}
If ($vault.webjobtype -eq "triggeredwebjobs")
{
if ($null -eq $vault.trigger_type) {throw "Missing trigger_type in settings file for $($subscription.subscriptionId)"}
}
}
If ($vault.webjobtype -eq "triggeredwebjobs" -and $vault.trigger_type -eq "scheduled")
{
if ($null -eq $vault.schedule) {throw "Missing schedule in settings file for $($subscription.subscriptionId)"}
If ($vault.webjobtype -eq "continuouswebjobs")
{
if ($null -eq $vault.continuous_type) {throw "Missing continuous_type in settings file for $($subscription.subscriptionId)"}
}
}
return $true
}
}
function Get-KuduApiAuthorisationHeaderValue($resourceGroupName, $webAppName)
{
$resourceType = "Microsoft.Web/sites/config"
$resourceName = "$webAppName/publishingcredentials"
$publishingCredentials = Invoke-AzureRmResourceAction -ResourceGroupName $resourceGroupName -ResourceType $resourceType -ResourceName $resourceName -Action list -ApiVersion $Apiversion -Force
return ("Basic {0}" -f [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $publishingCredentials.Properties.PublishingUserName, $publishingCredentials.Properties.PublishingPassword))))
}
function Publish-webjob
{
[OutputType([String])]
param
(
[parameter(Mandatory = $true)][string]$resourceGroupName,
[parameter(Mandatory = $true)][string]$webAppName,
[parameter(Mandatory = $true)][string]$Storagerg,
[parameter(Mandatory = $true)][string]$webjobname,
[parameter(Mandatory = $true)][string]$webjobtype,
[parameter(Mandatory = $true)][string]$storageAccountName,
[parameter(Mandatory = $true)][string]$container_name,
[parameter(Mandatory = $true)][string]$settingsFileName,
[parameter(Mandatory = $true)][string]$i
)
#Check resource group exist
try {
$resourceGroup = Get-AzureRmResourceGroup -Name $resourceGroupName -ErrorAction Stop
}
catch {
$resourceGroup = $null
}
if ($null -eq $resourceGroup)
{
$message = "Resource group $resourceGroupName not found, deployment stop"
Write-Verbose $message
return $message
}
else
{
# Prepare deployment variables
Write-Verbose "ResourceGroup Found"
$SettingsJson = Get-JsonParameterSet -settingsFileName $settingsFileName
$trigger_type = "$($SettingsJson.WorkLoads[$i].trigger_type)"
Write-Verbose $trigger_type
$schedule = "$($SettingsJson.WorkLoads[$i].schedule)"
Write-Verbose $schedule
$continuous_type = "$($SettingsJson.WorkLoads[$i].continuous_type)"
Write-Verbose $continuous_type
}
# Unlock ResourceGroup
Unlock-ResourceGroup $resourceGroupName
write-verbose "ResourceGroup Unlocked"
$accessToken = Get-KuduApiAuthorisationHeaderValue $resourceGroupName $webAppname
#Get storage account context and storage bolo
$sa= Get-AzureRmStorageAccount -ResourceGroupName $Storagerg -Name $storageAccountName
$ctx=$sa.Context
$blobs = Get-AzureStorageBlob -Container $container_name -Context $ctx
$webjobtype=$webjobtype+"webjobs"
$apiUrl = "https://$webAppName.scm.azurewebsites.net/api/$webjobtype/$webjobname"
#create a folder to save all the files of the container
$Location=$PSScriptRoot
New-Item -Path $Location -Name $webjobname -ItemType "directory" -Force
$folderPath = "$Location"+"\"+$webjobname
$localFile = $Location+"\"+$webjobname+"\"
#Generating header to create and publish the Webjob :
$Header = @{
"Content-Disposition"="attachment;filename=$($webAppName)"
"Authorization"=$accessToken
}
#Check if the storage container is empty
If($blobs.Count -eq 0)
{
Write-Error "The storage container is found empty"
}
#get files from container
foreach ($blob in $blobs)
{
$file=New-TemporaryFile
$file=Get-AzureStorageBlobContent -Container $container_name -Blob $blob.Name -Context $ctx -Destination $localFile -Force
$contents = Get-Content $localFile -Raw -ErrorAction:SilentlyContinue
$f=New-TemporaryFile
Add-Content $f $contents
}
If ($webjobtype -eq "triggeredwebjobs" -and $trigger_type -eq "scheduled")
{
$f = New-TemporaryFile
$r="{ ""schedule"" : "+""""+ $schedule+"""" + "}"
Add-Content $f $r
$destination=$Location+"\"+$webjobname+"\settings.job"
Move-Item -Path $f -Destination $destination
}
If ($webjobtype -eq "continuouswebjobs")
{
$f = New-TemporaryFile
If($continuous_type -eq "singleinstance")
{
$c="true"
}
If($continuous_type -eq "multipleinstance")
{
$c="false"
}
$r="{ ""is_singleton"" : " + $c + "}"
Add-Content $f $r
$destination=$Location+"\"+$webjobname+"\settings.job"
Move-Item -Path $f -Destination $destination
}
#Archive the files to a zip
$source = $localFile + "*"
$wz=$webjobname+".zip"
$destination = $Location+"\"+$webjobname+"\"+$wz
Compress-Archive -U -Path $source -DestinationPath $destination
#Deploying webjobs
$result = Invoke-RestMethod -Uri $apiUrl -Headers $Header -Method put -InFile $destination -ContentType 'application/zip' -ErrorAction Stop
Write-Host "Print result " -ForegroundColor Green
#delete the folder from local mahine
Remove-Item $folderPath -Force -Recurse -ErrorAction SilentlyContinue
# lock ResourceGroup
#Lock-ResourceGroup $resourceGroupName
write-verbose "ResourceGroup locked"
return $result
}
function Publish-Infrastructure
{
param(
[parameter(Mandatory = $true)][string]$settingsFileName
)
$settings = Get-JsonParameterSet -settingsFileName $settingsFileName
$deploymentIsSucceeded = $true
$workloadCount = $settings.WorkLoads.Count
Write-Verbose "workloadCounts: $workloadCount"
if($workloadCount -ge 1)
{
for($i = 0;$i -lt $workloadCount; $i++)
{
$applicationName = $settings.WorkLoads[$i].applicationName
Write-Verbose "application name: $applicationName"
$environmentName = $settings.WorkLoads[$i].environmentName
$applicationFile = "..\SettingsByWorkload\" + "nv_" + $applicationName + ".workload.json"
$applicationFile = Get-FileFullPath -fileName $applicationFile -rootPath $PSScriptRoot
$applicationFileJson = Get-JsonParameterSet -settingsFileName $applicationFile
Write-Verbose "application file json: $applicationName"
$null = Test-ParameterSet -settings $settings
$policyCount = $applicationFileJson.subscriptions.Count
Write-Verbose "$policyCount"
if($policyCount -ge 1)
{
for($j = 0;$j -lt $policyCount; $j++)
{
if($applicationFileJson.subscriptions[$j].environmentName -eq $environmentName)
{
$subscriptionId = $applicationFileJson.subscriptions[$j].subscriptionId
Write-Verbose "Environment Subscription: $($subscriptionId)"
Set-ContextIfNeeded -SubscriptionId $subscriptionId
foreach ($webjob in $settings.WorkLoads[$i])
{
$resourceGroupName = $webjob.resourceGroupName
$webAppName = $webjob.webAppName
$Storagerg = $webjob.Storagerg
$webjobname = $webjob.webjobname
$webjobtype = $webjob.webjobtype
$storageAccountName = $webjob.storageAccountName
$schedule = $webjob.schedule
$container_name = $webjob.container_name
$trigger_type = $webjob.trigger_type
Write-Verbose "Ready to start deployment on environment $EnvironmentName of a webjob in subscription $subscriptionId for resource group: $resourceGroupName"
$result = Publish-webjob ` -resourceGroupName $resourceGroupName `
-webAppName $webAppName `
-Storagerg $Storagerg `
-webjobname $webjobname `
-webjobtype $webjobtype `
-storageAccountName $storageAccountName `
-settingsFileName $settingsFileName `
-container_name $container_name `
-i $i
}
}
}
}
}
}
return $true
}
#START OF SCRIPT
if ($unitTestMode)
{
#do nothing
Write-Verbose 'Unit test mode, no deployment' -Verbose
}
else
{
#Log in Azure if not already done
try
{
$azureRmContext = Get-AzureRmContext -ErrorAction Stop
}
catch
{
$result = Add-AzureRmAccount
$azureRmContext = $result.Context
}
Write-Verbose "Subscription name $($azureRmContext.Subscription.Name)" -Verbose
$VerbosePreference = 'Continue'
# Get required templates and setting files. Throw if not found
$scriptsPath=$PSScriptRoot
$scriptsPath = Split-Path -Path $scriptsPath -Parent
$SettingsPath = Join-Path $scriptsPath $settingsFileName
$settingsFileName = $SettingsPath
Write-Verbose "Settings file name $($settingsFileName)" -Verbose
# Deploy infrastructure
return Publish-Infrastructure `
-settingsFileName $settingsFileName `
# END of script
}