The definitive guide on how to deploy a cloud service to Azure using PowerShell

This is a set of scripts:

deploy-all-async.ps1 > starts the deployment process asynchronously.
compile-all.ps1 > compiles all the projects synchronously
cloud-msbuild-compile.ps1 > compiles each project
cloud-deploy.ps1 > deploys the project to Azure

deploy-all-async.ps1

#To execute, cd to this folder and run:
# .\deploy-all-async.ps1

$ScriptPath = Split-Path $MyInvocation.InvocationName

#START COMPILE ********************************************************************************************************

$path = "$ScriptPath\compile-all.ps1"
Invoke-Expression "$path"

#END COMPILE ********************************************************************************************************


#START DEPLOY ********************************************************************************************************

$projects = @("clouddeploymentname1", "clouddeploymentname2", "clouddeploymentname3", "clouddeploymentname4", "clouddeploymentname5")

$projectFolderPaths = @{
"clouddeploymentname1" = "<path_to_project>\<project_folder>\"
"clouddeploymentname2" = "<path_to_project>\<project_folder>\"
"clouddeploymentname3" = "<path_to_project>\<project_folder>\"
"clouddeploymentname4" = "<path_to_project>\<project_folder>\"
"clouddeploymentname5" = "<path_to_project>\<project_folder>\"
}

$projectFileNames = @{
"clouddeploymentname1" = "<cloud deployment project name>"
"clouddeploymentname2" = "<cloud deployment project name>"
"clouddeploymentname3" = "<cloud deployment project name>"
"clouddeploymentname4" = "<cloud deployment project name>"
"clouddeploymentname5" = "<cloud deployment project name>"
}

Write-Output "Starting Jobs..."

foreach ($project in $projects.GetEnumerator()) {
Write-Host "$(Get-Date)> Going to Process: $project, $($projectFolderPaths.Get_Item($project)), $($projectFileNames.Get_Item($project))"

$ScriptBlock = { 
param($project, $projectFolderPath, $projectFileName)

$args = @()
$args += ("-service", $project)
$args += ("-slot", "Production")
$args += ("-AzureProjectFolderPath", $projectFolderPath)
$args += ("-AzureProjectFileName", $projectFileName)

$path = "<path>\cloud-deploy.ps1"

Write-Host "$(Get-Date)> Going to Execute deployment for: ($project, $projectFolderPath, $projectFileName)"
Invoke-Expression "$path $args"
}

Start-Job $ScriptBlock -Name "$project Deployment" -ArgumentList @($project, $projectFolderPaths.Get_Item($project), $projectFileNames.Get_Item($project))

Write-Host "Sleeping for 2 minutes between each deployment..."
Start-Sleep 120
}

#Wait for it all to complete
While (Get-Job -State "Running")
{
  Start-Sleep 10
}

Write-Output "Completed Jobs, getting output..."

# Getting the information back from the jobs
Get-Job | Receive-Job

#END DEPLOY ********************************************************************************************************

Write-Output "Completed All Jobs"

compile-all.ps1

$ScriptPath = Split-Path $MyInvocation.InvocationName

#START COMPILE ********************************************************************************************************

$path = "$ScriptPath\cloud-msbuild-compile.ps1"

#Needs to be done one by one as projects are shared...

$args = @()
$args += ("-AzureProjectFolderPath", "<path_to_project_folder>\")
$args += ("-AzureProjectFileName", "<project_file_name>")

Invoke-Expression "$path $args"

$args = @()
$args += ("-AzureProjectFolderPath", "<path_to_project_folder>\")
$args += ("-AzureProjectFileName", "<project_file_name>")

Invoke-Expression "$path $args"

$args = @()
$args += ("-AzureProjectFolderPath", "<path_to_project_folder>\")
$args += ("-AzureProjectFileName", "<project_file_name>")

Invoke-Expression "$path $args"

$args = @()
$args += ("-AzureProjectFolderPath", "<path_to_project_folder>\")
$args += ("-AzureProjectFileName", "<project_file_name>")

Invoke-Expression "$path $args"

$args = @()
$args += ("-AzureProjectFolderPath", "<path_to_project_folder>\")
$args += ("-AzureProjectFileName", "<project_file_name>")

Invoke-Expression "$path $args"

#END COMPILE ********************************************************************************************************

cloud-msbuild-compile.ps1

Param([string]$AzureProjectFolderPath,
 [string]$AzureProjectFileName)

Write-Output "$AzureProjectFileName|$(Get-Date)> Going to clear all files from bin\release folder..."

$releasepath = "bin\Release\"
Remove-Item $AzureProjectFolderPath$releasepath -recurse

#Creating a package

$msbuild = "'C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe'"

Write-Output "$AzureProjectFileName|$(Get-Date)> Going to build package IGNORING POST BUILD EVENTS..."

#IGNORES POST BUILD EVENTS!!!

$args = $AzureProjectFolderPath + $AzureProjectFileName + ".ccproj /p:Configuration=Release /p:DebugType=None /p:Platform=AnyCpu /p:OutputPath=" + $AzureProjectFolderPath + $releasepath + " /p:TargetProfile=Cloud /t:publish /verbosity:quiet /p:VisualStudioVersion=14.0 /p:PreBuildEvent= /p:PostBuildEvent="

Invoke-Expression "& $msbuild $args"


Write-Output "$AzureProjectFileName|$(Get-Date)> Build package completed"

cloud-deploy.ps1

Param([string]$service,
      [string]$slot,
 [string]$AzureProjectFolderPath,
 [string]$AzureProjectFileName)

Write-Output "$AzureProjectFileName|$(Get-Date)> Going to deploy..."

#Deploying a package
Function Get-File($filter){
    [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
    $fd = New-Object system.windows.forms.openfiledialog
    $fd.MultiSelect = $false
    $fd.Filter = $filter
    [void]$fd.showdialog()
    return $fd.FileName
}

#Locate the package, publish settings and other variables
Write-Output "$AzureProjectFileName|$(Get-Date)> Locating the package, publish settings and other variables..."

if (!$service) {
$service = "<default>"
}

if (!$slot) {
$slot = "Production"
}

[string]$package = $AzureProjectFolderPath + "bin\Release\app.publish\" + $AzureProjectFileName + ".cspkg"
Write-Output "$AzureProjectFileName|$(Get-Date)> $package= $($package)"

[string]$config = $AzureProjectFolderPath + "bin\Release\app.publish\ServiceConfiguration.Cloud.cscfg"
Write-Output "$AzureProjectFileName|$(Get-Date)> $config= $($config)" 

[string]$publishsettings = "<path to publish settings file>"
[string]$storageaccount = "<name of storage account>"
[string]$subscription = "<name of subscription>"
[string]$containerName = "psdeploy"

#Functions

Function Set-AzureSettings($publishsettings, $subscription, $storageaccount){
    Import-AzurePublishSettingsFile -PublishSettingsFile $publishsettings

    Set-AzureSubscription -SubscriptionName $subscription -CurrentStorageAccount $storageaccount

    Select-AzureSubscription -SubscriptionName $subscription
}

Function Upload-Package($package, $containerName){
    $blob = "$service.package.$(get-date -f yyyy_MM_dd_hh_ss).cspkg"
     
    $containerState = Get-AzureStorageContainer -Name $containerName -ea 0
    if ($containerState -eq $null)
    {
        New-AzureStorageContainer -Name $containerName | out-null
    }
     
    Set-AzureStorageBlobContent -File $package -Container $containerName -Blob $blob -Force| Out-Null
    $blobState = Get-AzureStorageBlob -blob $blob -Container $containerName

    $blobState.ICloudBlob.uri.AbsoluteUri
}

Function Create-Deployment($package_url, $service, $slot, $config){
    $stat = New-AzureDeployment -Slot $slot -Package $package_url -Configuration $config -ServiceName $service
}

Function Upgrade-Deployment($package_url, $service, $slot, $config){
    $setdeployment = Set-AzureDeployment -Upgrade -Slot $slot -Package $package_url -Configuration $config -ServiceName $service -Force
}

Function Check-Deployment($service, $slot){
    $completeDeployment = Get-AzureDeployment -ServiceName $service -Slot $slot
    $completeDeployment.deploymentid
}

#End Functions

try
{
#Importing the Azure cmdlets module
Write-Output "$AzureProjectFileName|$(Get-Date)> Importing the Azure cmdlets module..."

Import-Module "C:\Program Files (x86)\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Azure.psd1"

#Import the publish profile and configure the subscription
Write-Output "$AzureProjectFileName|$(Get-Date)> Importing the publish profile and configuring the subscription..."

Set-AzureSettings -publishsettings $publishsettings -subscription $subscription -storageaccount $storageaccount

#Upload the package to blob storage
Write-Output "$AzureProjectFileName|$(Get-Date)> Uploading the package to blob storage..."

$package_url = Upload-Package -package $package -containerName $containerName

#Check if a deployment exists
Write-Output "$AzureProjectFileName|$(Get-Date)> Checking if a deployment exists..."

$deployment = Get-AzureDeployment -ServiceName $service -Slot $slot -ErrorAction silentlycontinue

#Create a new deployment

if ($deployment.Name -eq $null) 
{
Write-Output "$AzureProjectFileName|$(Get-Date)> Creating a new deployment..."
    Create-Deployment -package_url $package_url -service $service -slot $slot -config $config


#Upgrade an existing deployment

if ($deployment.Name -eq $null) 
{
    #Invalid State

else 
{
Write-Output "$AzureProjectFileName|$(Get-Date)> Upgrade an existing deployment..."
    Upgrade-Deployment -package_url $package_url -service $service -slot $slot -config $config
}

#Check if the deployment has succeeded
Write-Output "$AzureProjectFileName|$(Get-Date)> Checking if the deployment has succeeded..."

$deploymentid = Check-Deployment -service $service -slot $slot

Write-Output "$AzureProjectFileName|$(Get-Date)> Completed"
exit 0
}
catch [System.Exception] 
{
Write-Host $_.Exception.ToString()
    exit 1
}

Comments

Popular posts from this blog

Tutorial: Using Google Cloud Storage from C# and .NET

Late 2008 Macbook only giving 1.5 gb/s speed with 6 gb/s Intel SSD?

The ridiculous interview experience