Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion MBrace.Azure.sln
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25123.0
VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{8C962C9C-7DF5-430C-8CD4-7C2642F68409}"
ProjectSection(SolutionItems) = preProject
Expand Down Expand Up @@ -57,6 +57,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WorkerRole", "WorkerRole",
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "MBrace.Azure.StandaloneClient", "samples\MBrace.Azure.StandaloneClient\MBrace.Azure.StandaloneClient.fsproj", "{C1F585DB-92AA-4CF2-AB64-CF1857A5B672}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "resourcemanager", "resourcemanager", "{A568C626-7CD1-4C4C-A45C-4406B51066C0}"
ProjectSection(SolutionItems) = preProject
deployment\azuredeploy.json = deployment\azuredeploy.json
deployment\azuredeploy.template.json = deployment\azuredeploy.template.json
deployment\large-cluster.json = deployment\large-cluster.json
deployment\medium-cluster.json = deployment\medium-cluster.json
deployment\small-cluster.json = deployment\small-cluster.json
deployment\tiny-cluster.json = deployment\tiny-cluster.json
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug_AzureSDK|Any CPU = Debug_AzureSDK|Any CPU
Expand Down Expand Up @@ -131,6 +141,7 @@ Global
{2F80E0B8-69D4-4492-A0EE-73B98C741A04} = {1CCF30B5-03E2-423A-85A9-98278969CAAF}
{6EE518A6-354B-4FA0-B9D4-08F41CA65960} = {1CCF30B5-03E2-423A-85A9-98278969CAAF}
{C1F585DB-92AA-4CF2-AB64-CF1857A5B672} = {5F24F335-F43F-4266-B9DD-E5027835DAAB}
{A568C626-7CD1-4C4C-A45C-4406B51066C0} = {BC64BD78-3886-4FC5-A6F9-2A71A99769B9}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EnterpriseLibraryConfigurationToolBinariesPathV6 = packages\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\lib\portable-net45+win+wp8;packages\EnterpriseLibrary.TransientFaultHandling.Data.6.0.1304.1\lib\NET45
Expand Down
49 changes: 47 additions & 2 deletions build.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ let csdefTemplate = "src" @@ "MBrace.Azure.CloudService" @@ "ServiceDefinition.c
let csdefForSize size = "src" @@ "MBrace.Azure.CloudService" @@ "ServiceDefinition" + size + ".csdef"
let cspkgAfterBuild configuration = "bin" @@ "cspkg" @@ "app.publish" @@ "MBrace.Azure.CloudService.cspkg"
let cspkgAfterCopy size = "bin" @@ "cspkg" @@ "MBrace.Azure.CloudService-" + size + ".cspkg"
let vmWorkerZip = "bin" @@ "MBrace.Azure.zip"
let webjobZip = "bin" @@ "MBrace.Azure.Worker.zip"
let azureDeployTemplate = "src" @@ "MBrace.Azure.ResourceManager" @@ "azuredeploy.template.json"
let generatedAzureDeploy = "deployment" @@ "azuredeploy.json"

// See https://azure.microsoft.com/en-gb/documentation/articles/cloud-services-sizes-specs/
let vmSizes =
Expand All @@ -95,7 +99,40 @@ Target "Build" (fun _ ->
|> Log "AppBuild-Output: "
)

// Build lots of packages for differet VM sizes
let filesForZip =

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Format one-file-per-line so it's easier to see what's in the zip?

I suppose there's no other way to get this list of files....?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there is, we could scrape the bin directory but we'd end up with assemblies which aren't really necessary like all of the Azure management libraries.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is an easier way to maintain the blacklist of the files that we don't want and subtract that from the set of all files?

[
"Argu.dll"
"FSharp.Core.dll"
"FSharp.Core.xml"
"FsPickler.dll"
"FsPickler.Json.dll"
"MBrace.Azure.dll"
"MBrace.Azure.pdb"
"MBrace.Azure.XML"
"mbrace.azureworker.exe"
"mbrace.azureworker.exe.config"
"MBrace.Core.dll"
"MBrace.Core.pdb"
"MBrace.Core.xml"
"MBrace.Runtime.dll"
"MBrace.Runtime.pdb"
"MBrace.Runtime.xml"
"Microsoft.Azure.KeyVault.Core.dll"
"Microsoft.Data.Edm.dll"
"Microsoft.Data.OData.dll"
"Microsoft.Data.Services.Client.dll"
"Microsoft.ServiceBus.dll"
"Microsoft.WindowsAzure.Storage.dll"
"Mono.Cecil.dll"
"Newtonsoft.Json.dll"
"System.Collections.Immutable.dll"
"System.Reflection.Metadata.dll"
"System.Spatial.dll"
"Vagabond.AssemblyParser.dll"
"Vagabond.dll"
]

// Build lots of packages for differet VM sizes and deployment methods
Target "BuildPackages" (fun _ ->
for size in vmSizes do
csdefTemplate |> CopyFile (csdefForSize size)
Expand All @@ -106,7 +143,14 @@ Target "BuildPackages" (fun _ ->
|> MSBuild "" "Publish" ["Configuration", configuration + "_AzureSDK"; "ServiceVMSize", size]
|> Log "AppPackage-Output: "
(cspkgAfterBuild configuration) |> CopyFile (cspkgAfterCopy size)


CreateDir "bin/app_data/jobs/continuous/MBraceWorker"
filesForZip
|> List.iter (fun file -> CopyFile ("bin/app_data/jobs/continuous/MBraceWorker" @@ file) ("bin" @@ file))
ZipHelper.CreateZip "bin" webjobZip "" 0 false (filesForZip |> List.map ((@@) "bin/app_data/jobs/continuous/MBraceWorker"))
ZipHelper.CreateZip "bin" vmWorkerZip "" 0 false (filesForZip |> List.map ((@@) "bin"))
azureDeployTemplate |> CopyFile generatedAzureDeploy
generatedAzureDeploy |> ReplaceInFile (fun s -> s.Replace("<VERSION_NUMBER>", release.NugetVersion))
)

// --------------------------------------------------------------------------------------
Expand Down Expand Up @@ -208,6 +252,7 @@ Target "ReleaseGithub" (fun _ ->
client
|> createDraft gitOwner gitName release.NugetVersion (release.SemVer.PreRelease <> None) release.Notes
|> uploadFiles (Seq.map cspkgAfterCopy vmSizes)
|> uploadFiles (["deployment" @@ "azuredeploy.json"; "deployment" @@ "tiny-cluster.json"; "deployment" @@ "small-cluster.json"; "deployment" @@ "medium-cluster.json"; "deployment" @@ "large-cluster.json"; vmWorkerZip; webjobZip])
|> releaseDraft
|> Async.RunSynchronously
)
Expand Down
48 changes: 48 additions & 0 deletions deployment/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# MBrace Deployment with Azure Resource Manager
Deploy an MBrace cluster to Azure as an App Service webjob along with all of the required additional Azure dependencies.

## How to use
1. Open up a Powershell window.
2. CD to this directory.
3. Execute the following commands:

```lang=powershell
## Logs into Azure using your credentials - no need for pub setting
Login-AzureRmAccount

## Create a "resource group" for the cluster, called MyCluster
New-AzureRmResourceGroup -Name MyCluster -Location "North Europe"

4. You will notice the output of this operation will contain the Service Bus and Storage Account keys - these can be used to connect to the cluster.

5. You can easily fine tune the process as follows:

## Optional, if you have multiple subscriptions
Set-AzureRmContext -SubscriptionName "My Subscription"

## Create an 'small' MBrace cluster called MyCluster
New-AzureRmResourceGroupDeployment -ResourceGroupName MyCluster -TemplateFile .\azuredeploy.json -TemplateParameterFile "small-cluster.json"

## Resize the cluster to a 'medium' sized cluster (2 nodes)
New-AzureRmResourceGroupDeployment -ResourceGroupName MyCluster -TemplateFile .\azuredeploy.json -TemplateParameterFile "medium-cluster.json"

## Manually configure the cluster size to 8 large nodes (S3 = large)
New-AzureRmResourceGroupDeployment -ResourceGroupName MyCluster -TemplateFile .\azuredeploy.json -clusterSize 8 -nodeSize S3

## Destroy the cluster
Remove-AzureRmResourceGroup -Name "MyCluster"
```

## Benefits over Cloud Service deployment
* Rapid provisioning / deprovisioning
* Code-free - no requirements for MBrace to use MAML to provision a cluster
* Simpler model for cluster provisioning with ready-made "small" "medium" and "large" cluster parameter files.
* Built in Azure diagnostics / charting within the Portal
* Fully supported by Microsoft going forwards
* Easier management - a single MBrace Worker executable / package that is accessible over HTTP can function across
all node sizes, unlike Cloud Services. Packages are simple zip files - no need to create cspackages.

## Restrictions
* Requires PowerShell currently. This could be removed using the .NET ARM SDK
* As this implementation of MBrace runs in a web job in the Azure App Service, it does not have admin privileges. Therefore, it cannot retrieve PerfMon
counters for the purposes of metrics e.g. ``ShowWorkers()``.
152 changes: 152 additions & 0 deletions deployment/azuredeploy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"alwaysOn": {
"type": "bool",
"defaultValue": true
},
"nodeSize": {
"type": "string",
"defaultValue": "F1",
"allowedValues": [
"F1",
"D1",
"B1",
"B2",
"B3",
"S1",
"S2",
"S3",
"P1",
"P2",
"P3",
"P4"
],
"metadata": {
"description": "The size of each node. Check details at https://azure.microsoft.com/en-us/pricing/details/app-service/"
}
},
"clusterSize": {
"type": "int",
"defaultValue": 1,
"minValue": 1,
"metadata": {
"description": "The number of nodes in a cluster."
}
}
},
"variables": {
"farmName": "[concat('mbfarm-', uniqueString(resourceGroup().id))]",
"serverFarmId": "[concat('Microsoft.Web/serverfarms/', variables('farmName'))]",
"storageAccount": "[concat('mbstorage', uniqueString(resourceGroup().id))]",
"serviceBus": "[concat('mbmsg', uniqueString(resourceGroup().id))]",
"serviceBusAuthRule": "[resourceId('Microsoft.ServiceBus/namespaces/authorizationRules', variables('serviceBus'), 'RootManageSharedAccessKey')]",
"webappName": "[concat('mbapp-', uniqueString(resourceGroup().id))]"
},
"resources": [
{
"name": "[variables('storageAccount')]",
"type": "Microsoft.Storage/storageAccounts",
"location": "[resourceGroup().location]",
"apiVersion": "2015-06-15",
"dependsOn": [],
"tags": {
"displayName": "Storage Account"
},
"properties": {
"accountType": "Standard_LRS"
}
},
{
"name": "[variables('serviceBus')]",
"type": "Microsoft.ServiceBus/namespaces",
"location": "[resourceGroup().location]",
"apiVersion": "2015-08-01",
"dependsOn": [],
"properties": {}
},
{
"type": "Microsoft.Web/serverfarms",
"name": "[variables('farmName')]",
"apiVersion": "2015-08-01",
"location": "[resourceGroup().location]",
"tags": {
"displayName": "Service Farm"
},
"sku": {
"name": "[parameters('nodeSize')]",
"capacity": "[parameters('clusterSize')]"
},
"properties": {
"name": "[variables('farmName')]"
}
},
{
"name": "[variables('webappName')]",
"type": "Microsoft.Web/sites",
"location": "[resourceGroup().location]",
"apiVersion": "2015-08-01",
"dependsOn": [
"[variables('serverFarmId')]",
"[concat('Microsoft.ServiceBus/namespaces/', variables('serviceBus'))]",
"[concat('Microsoft.Storage/storageAccounts/', variables('storageAccount'))]"
],
"tags": {
"[concat('hidden-related:', resourceGroup().id, variables('serverFarmId'))]": "Resource",
"displayName": "MBraceWorker"
},
"properties": {
"name": "[variables('webappName')]",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms/', variables('farmName'))]",
"siteConfig": {
"AlwaysOn": "[parameters('alwaysOn')]"
}
},
"resources": [
{
"name": "appsettings",
"apiVersion": "2015-08-01",
"type": "config",
"properties": {
"storage connection string": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccount'), ';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccount')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]",
"service bus connection string": "[listkeys(variables('serviceBusAuthRule'), '2015-08-01').primaryConnectionString]"
},
"tags": {
"displayName": "MBraceWorkerSettings"
},
"dependsOn": [
"[concat('Microsoft.Web/sites/', variables('webappName'))]"
]
},
{
"name": "MSDeploy",
"type": "extensions",
"location": "[resourceGroup().location]",
"apiVersion": "2015-08-01",
"dependsOn": [
"[concat('Microsoft.Web/sites/', variables('webappName'))]"
],
"tags": {
"displayName": "webdeploy"
},
"properties": {
"packageUri": "https://isaac.blob.core.windows.net/data/mbraceworker.zip",
"dbType": "None",
"connectionString": ""
}
}
]
}
],
"outputs": {
"storageConnectionString": {
"type": "string",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccount'), ';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccount')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]"
},
"serviceBusConnectionString": {
"type": "string",
"value": "[listkeys(variables('serviceBusAuthRule'), '2015-08-01').primaryConnectionString]"
}
}
}
8 changes: 8 additions & 0 deletions deployment/large-cluster.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"nodeSize": { "value": "S3" },
"clusterSize": { "value": 4 }
}
}
8 changes: 8 additions & 0 deletions deployment/medium-cluster.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"nodeSize": { "value": "B2" },
"clusterSize": { "value": 3 }
}
}
8 changes: 8 additions & 0 deletions deployment/small-cluster.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"nodeSize": { "value": "B1" },
"clusterSize": { "value": 1 }
}
}
9 changes: 9 additions & 0 deletions deployment/tiny-cluster.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"nodeSize": { "value": "F1" },
"clusterSize": { "value": 1 },
"alwaysOn": { "value": false }
}
}
Loading