This is step by step guide to provision an Azure Service Fabric using PowerShell.
- Windows 7 or later
- Administrator privileges
- An active Azure subscription
Open a Windows Powershell window as Administrator, and at the prompt run:
Write-Host $PSVersionTable.PSVersion
which will print out the current version of PowerShell installed on the machine. If the version is version 4 or lower, install the latest version of PowerShell, which is part of the Windows Management Framework 5.1 or above: https://www.microsoft.com/en-us/download/details.aspx?id=54616
Next check that you have PowerShellGet installed. You can check by running command
Get-Module PowerShellGet -list | Select-Object Name,Version,Path
which will produce the following output if PowerShellGet is present
Name Version Path
---- ------- ----
PowerShellGet 1.0.0.1 C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PowerShellGet.psd1
If PowerShellGet is not installed, install WMF 5+ from https://www.microsoft.com/en-us/download/details.aspx?id=54616
Install-Module AzureRM #install the Azure PowerShell from the PowerShell gallery
Import-Module AzureRM
Login-AzureRmAccount # Login into Azure, and enter your Azure subscription credentials when prompted
# Create some resource groups to hold the key vault and cluster
$locationRegion = "Southeast Asia" # You can use any region that supports service cluster
New-AzureRmResourceGroup -Name "sf-keyvault" -Location $locationRegion
New-AzureRmResourceGroup -Name "sf-cluster" -Location $locationRegion
Separate resource groups are provide a convenient way of recreating the cluster, without having to recreate the key vault.
Download the PowerShell cmdlet Invoke-AddCertToKeyVault
which is part of the Azure PowerShell helpers from https://github.com/ChackDan/Service-Fabric Once downloaded, import the module
Import-Module "<path>\ServiceFabricRPHelpers.psm1"
Next get the subscription Id you are wanting to use for the provisioning. These can be obtained by running:
Get-AzureRmSubscription
and take note of the subscription Id. Once you have this, you can create the key vault and a self-signed certificate. if you already have a certificate, this may be used instead of the self-signed certificate. The key vault and service fabric cluster must reside in the same region, so choose this region carefully otherwise you'll have to recreate the key vault if the service fabric moves to another region.
$ResourceGroup = "sf-keyvault"
$VName = "sf-vault"
New-AzureRmKeyVault -VaultName $VName -ResourceGroupName $ResourceGroup -Location $locationRegion -EnabledForDeployment
This command will produce output similar to the following:
Vault Name : sf-vault
Resource Group Name : sf-keyvault
Location : Southeast Asia
Resource ID : /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxx/resourceGroups/sf-vault/providers/Microsoft.KeyVault/vaults/sf-vault
Vault URI : https://sf-vault.vault.azure.net
Tenant ID : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxx
SKU : Standard
Enabled For Deployment? : True
Enabled For Template Deployment? : False
Enabled For Disk Encryption? : False
Soft Delete Enabled? :
Access Policies :
Tenant ID : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxx
Object ID : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxx
Application ID :
Display Name : John Doe
Permissions to Keys : get, create, delete, list, update, import, backup, restore, recover
Permissions to Secrets : get, list, set, delete, backup, restore, recover
Permissions to Certificates : get, delete, list, create, import, update, deleteissuers, getissuers, listissuers, managecontacts, manageissuers, setissuers
Then create a self-signed certificate and add this certificate to the key vault.
$SubscriptionID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxx"
$newCertName = "clustercert"
$dnsName = "https://sf-vault.vault.azure.net/" #The certificate's subject name must match the domain used to access the Service Fabric cluster.
$localCertPath = "C:\MyCertificates" # location where you want the .PFX to be stored
Invoke-AddCertToKeyVault -SubscriptionId $SubscriptionID -ResourceGroupName $ResourceGroup -Location $locationRegion -VaultName $VName -CertificateName $newCertName -CreateSelfSignedCertificate -DnsName $dnsName -OutputPath $localCertPath
This will produce output similar too:
Name Value
---- -----
CertificateThumbprint yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
SourceVault /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxx/resourceGroups/sf-keyvault/providers/Microsoft.KeyVault/vaults/sf-vault
CertificateURL https://sf-vault.vault.azure.net:443/secrets/clustercert/zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
Copy this information to a text file because needed to create the deployment template later.
Install the certificate in the local machines certificate store. This can be done by opening the file C:\MyCertificates\clustercert.pfx
and placing it into the certicate store for Current User
. Any machine used to start, stop, update the service fabric deployment will need this certificate to be installed in the machines certificate store.
First create a resource group for the cluster
$ResouceGroup = "sf-cluster"
$locationRegion = "Southeast Asia"
New-AzureRmResourceGroup -Name $ResouceGroup -Location $locationRegion
Here is a deployment template based on the templates given in : https://github.com/Azure/azure-quickstart-templates/tree/master/service-fabric-secure-cluster-5-node-1-nodetype This json should be placed in a file named azuredeploy.parameters.json
.
In order to reduce the cost we have altered the template to use three A1 virtual machines.
This template will need to be customized for your configuration. The certificate related values that need to be changed can be obtained using:
$VaultName = (Get-AzureRmKeyVault).VaultName
- The
sourceVaultvalue
value can be retrieved using the commandGet-AzureRmKeyVault
. - The
clusterCertificateUrlValue
value can be retrieved using the commandGet-AzureKeyVaultSecret -VaultName $VaultName -Name (Get-AzureKeyVaultSecret -VaultName $VaultName).Name
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"clusterLocation": {
"value": "southeastasia"
},
"clusterName": {
"value": "sf-cluster"
},
"adminUserName": {
"value": "admuser"
},
"adminPassword": {
"value": "Pa$$word$1"
},
"vmImagePublisher": {
"value": "MicrosoftWindowsServer"
},
"vmImageOffer": {
"value": "WindowsServer"
},
"vmImageSku": {
"value": "2016-Datacenter"
},
"vmImageVersion": {
"value": "latest"
},
"loadBalancedAppPort1": {
"value": 80
},
"loadBalancedAppPort2": {
"value": 8081
},
"certificateStorevalue": {
"value": "My"
},
"certificateThumbprint": {
"value": "99912345o458045827c723047234"
},
"sourceVaultvalue": {
"value": "/subscriptions/<Sub ID>/resourceGroups/<Resource group name>/providers/Microsoft.KeyVault/vaults/<vault name>"
},
"certificateUrlvalue": {
"value": "https://sf-vault.vault.azure.net:443/secrets/<exact location>"
},
"clusterProtectionLevel": {
"value": "EncryptAndSign"
},
"storageAccountType": {
"value": "Standard_LRS"
},
"supportLogStorageAccountType": {
"value": "Standard_LRS"
},
"applicationDiagnosticsStorageAccountType": {
"value": "Standard_LRS"
},
"nodeTypeSize": {
"value": "Standard_A1"
},
"nt0InstanceCount": {
"value": 3
},
"nodeTypeReliabilityLevel": {
"value": "Bronze"
}
}
}
The accompanying deployment template is stored in azuredeploy.json
.
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
"contentVersion": "1.0.0.0",
"parameters": {
"clusterLocation": {
"type": "string",
"metadata": {
"description": "Location of the Cluster"
}
},
"clusterName": {
"type": "string",
"defaultValue": "sf-cluster",
"metadata": {
"description": "Name of your cluster - Between 3 and 23 characters. Letters and numbers only"
}
},
"adminUserName": {
"type": "string",
"metadata": {
"description": "Remote desktop user Id"
}
},
"adminPassword": {
"type": "securestring",
"metadata": {
"description": "Remote desktop user password. Must be a strong password"
}
},
"vmImagePublisher": {
"type": "string",
"defaultValue": "MicrosoftWindowsServer",
"metadata": {
"description": "VM image Publisher"}
},
"vmImageOffer": {
"type": "string",
"defaultValue": "WindowsServer",
"metadata": {
"description": "VM image offer"}
},
"vmImageSku": {
"type": "string",
"defaultValue": "2012-R2-Datacenter",
"metadata": {
"description": "VM image SKU"}
},
"vmImageVersion": {
"type": "string",
"defaultValue": "latest",
"metadata": {
"description": "VM image version"}
},
"loadBalancedAppPort1": {
"type": "int",
"defaultValue": 80,
"metadata": {
"description": "Input endpoint1 for the application to use. Replace it with what your application uses"
}
},
"loadBalancedAppPort2": {
"type": "int",
"defaultValue": 8081,
"metadata": {
"description": "Input endpoint2 for the application to use. Replace it with what your application uses"
}
},
"sourceVaultValue": {
"type": "string",
"metadata": {
"description": "Resource Id of the key vault, is should be in the format of /subscriptions/<Sub ID>/resourceGroups/<Resource group name>/providers/Microsoft.KeyVault/vaults/<vault name>"
}
},
"clusterProtectionLevel": {
"type": "string",
"allowedValues": [
"None",
"Sign",
"EncryptAndSign"
],
"defaultValue": "EncryptAndSign",
"metadata": {
"description": "Protection level.Three values are allowed - EncryptAndSign, Sign, None. It is best to keep the default of EncryptAndSign, unless you have a need not to"
}
},
"storageAccountType": {
"type": "string",
"allowedValues": [
"Standard_LRS",
"Standard_GRS"
],
"defaultValue": "Standard_LRS",
"metadata": {
"description": "Replication option for the VM image storage account"
}
},
"supportLogStorageAccountType": {
"type": "string",
"allowedValues": [
"Standard_LRS",
"Standard_GRS"
],
"defaultValue": "Standard_LRS",
"metadata": {
"description": "Replication option for the support log storage account"
}
},
"applicationDiagnosticsStorageAccountType": {
"type": "string",
"allowedValues": [
"Standard_LRS",
"Standard_GRS"
],
"defaultValue": "Standard_LRS",
"metadata": {
"description": "Replication option for the application diagnostics storage account"
}
},
"nodeTypeSize": {
"type": "string",
"metadata": {
"description": "Node Type size of the Cluster"
}
},
"nt0InstanceCount": {
"type": "int",
"defaultValue": 3,
"metadata": {
"description": "Instance count for node type"
}
},
"nodeTypeReliabilityLevel": {
"type": "string",
"metadata": {
"description": "It can be one of 'Platinum'(9 replicas), 'Gold'(7 replicas), Silver'(5 replicas) and 'Bronze'(3 replicas)"
}
},
"clusterCertificateUrlValue": {
"type": "string",
"metadata": {
"description": "Refers to the location URL in your key vault where the certificate was uploaded, it is should be in the format of https://<name of the vault>.vault.azure.net:443/secrets/<exact location>"
}
},
"clusterCertificateThumbprint": {
"type": "string",
"metadata": {
"description": "Cluster Certificate Thumbprint"
}
},
"clusterCertificateStoreValue": {
"type": "string",
"allowedValues": [
"My"
],
"defaultValue": "My",
"metadata": {
"description": "The store name where the cert will be deployed in the virtual machine"
}
}
},
"variables": {
"computeLocation": "[parameters('clusterLocation')]",
"dnsName": "[parameters('clusterName')]",
"vmStorageAccountName": "[toLower(concat(uniqueString(resourceGroup().id), '1' ))]",
"vmName": "vm",
"publicIPAddressName": "PublicIP-VM",
"publicIPAddressType": "Dynamic",
"vmStorageAccountContainerName": "vhds",
"virtualNetworkName": "VNet",
"addressPrefix": "10.0.0.0/16",
"nicName": "NIC",
"lbName": "LoadBalancer",
"lbIPName": "PublicIP-LB-FE",
"availSetName": "AvailabilitySet",
"maxPercentUpgradeDomainDeltaUnhealthyNodes": "100",
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]",
"overProvision": "false",
"vmssApiVersion": "2016-03-30",
"lbApiVersion": "2015-06-15",
"vNetApiVersion": "2015-06-15",
"storageApiVersion": "2016-01-01",
"publicIPApiVersion": "2015-06-15",
"nt0applicationStartPort": "20000",
"nt0applicationEndPort": "30000",
"nt0ephemeralStartPort": "49152",
"nt0ephemeralEndPort": "65534",
"nt0fabricTcpGatewayPort": "19000",
"nt0fabricHttpGatewayPort": "19080",
"subnet0Name": "Subnet-0",
"subnet0Prefix": "10.0.0.0/24",
"subnet0Ref": "[concat(variables('vnetID'),'/subnets/',variables('subnet0Name'))]",
"supportLogStorageAccountName": "[toLower( concat(uniqueString(resourceGroup().id),'2', 'supportlog'))]",
"applicationDiagnosticsStorageAccountName": "[toLower( concat(uniqueString(resourceGroup().id),'3', 'servicelog'))]",
"lbID0": "[resourceId('Microsoft.Network/loadBalancers',concat('LB','-', parameters('clusterName'),'-',variables('vmNodeType0Name')))]",
"lbIPConfig0": "[concat(variables('lbID0'),'/frontendIPConfigurations/LoadBalancerIPConfig')]",
"lbPoolID0": "[concat(variables('lbID0'),'/backendAddressPools/LoadBalancerBEAddressPool')]",
"lbProbeID0": "[concat(variables('lbID0'),'/probes/FabricGatewayProbe')]",
"lbHttpProbeID0": "[concat(variables('lbID0'),'/probes/FabricHttpGatewayProbe')]",
"lbNatPoolID0": "[concat(variables('lbID0'),'/inboundNatPools/LoadBalancerBEAddressNatPool')]",
"vmNodeType0Name": "[toLower(concat('NT1', variables('vmName')))]",
"vmNodeType0Size": "[parameters('nodeTypeSize')]",
"vmStorageAccountName0": "[toLower(concat(uniqueString(resourceGroup().id), '1', '0' ))]",
"uniqueStringArray0": [
"[concat(variables('vmStorageAccountName0'), '0')]",
"[concat(variables('vmStorageAccountName0'), '1')]",
"[concat(variables('vmStorageAccountName0'), '2')]",
"[concat(variables('vmStorageAccountName0'), '3')]",
"[concat(variables('vmStorageAccountName0'), '4')]"
]
},
"resources": [
{
"apiVersion": "[variables('storageApiVersion')]",
"type": "Microsoft.Storage/storageAccounts",
"name": "[variables('supportLogStorageAccountName')]",
"location": "[variables('computeLocation')]",
"dependsOn": [],
"properties": {},
"kind": "Storage",
"sku": {
"name": "[parameters('supportLogStorageAccountType')]"
},
"tags": {
"resourceType": "Service Fabric",
"clusterName": "[parameters('clusterName')]"
}
},
{
"apiVersion": "[variables('storageApiVersion')]",
"type": "Microsoft.Storage/storageAccounts",
"name": "[variables('applicationDiagnosticsStorageAccountName')]",
"location": "[variables('computeLocation')]",
"dependsOn": [],
"properties": {},
"kind": "Storage",
"sku": {
"name": "[parameters('applicationDiagnosticsStorageAccountType')]"
},
"tags": {
"resourceType": "Service Fabric",
"clusterName": "[parameters('clusterName')]"
}
},
{
"apiVersion": "[variables('vNetApiVersion')]",
"type": "Microsoft.Network/virtualNetworks",
"name": "[variables('virtualNetworkName')]",
"location": "[variables('computeLocation')]",
"properties": {
"addressSpace": {
"addressPrefixes": [
"[variables('addressPrefix')]"
]
},
"subnets": [
{
"name": "[variables('subnet0Name')]",
"properties": {
"addressPrefix": "[variables('subnet0Prefix')]"
}
}
]
},
"tags": {
"resourceType": "Service Fabric",
"clusterName": "[parameters('clusterName')]"
}
},
{
"apiVersion": "[variables('publicIPApiVersion')]",
"type": "Microsoft.Network/publicIPAddresses",
"name": "[concat(variables('lbIPName'),'-','0')]",
"location": "[variables('computeLocation')]",
"properties": {
"dnsSettings": {
"domainNameLabel": "[variables('dnsName')]"
},
"publicIPAllocationMethod": "Dynamic"
},
"tags": {
"resourceType": "Service Fabric",
"clusterName": "[parameters('clusterName')]"
}
},
{
"apiVersion": "[variables('lbApiVersion')]",
"type": "Microsoft.Network/loadBalancers",
"name": "[concat('LB','-', parameters('clusterName'),'-',variables('vmNodeType0Name'))]",
"location": "[variables('computeLocation')]",
"dependsOn": [
"[concat('Microsoft.Network/publicIPAddresses/',concat(variables('lbIPName'),'-','0'))]"
],
"properties": {
"frontendIPConfigurations": [
{
"name": "LoadBalancerIPConfig",
"properties": {
"publicIPAddress": {
"id": "[resourceId('Microsoft.Network/publicIPAddresses',concat(variables('lbIPName'),'-','0'))]"
}
}
}
],
"backendAddressPools": [
{
"name": "LoadBalancerBEAddressPool",
"properties": {}
}
],
"loadBalancingRules": [
{
"name": "LBRule",
"properties": {
"backendAddressPool": {
"id": "[variables('lbPoolID0')]"
},
"backendPort": "[variables('nt0fabricTcpGatewayPort')]",
"enableFloatingIP": "false",
"frontendIPConfiguration": {
"id": "[variables('lbIPConfig0')]"
},
"frontendPort": "[variables('nt0fabricTcpGatewayPort')]",
"idleTimeoutInMinutes": "5",
"probe": {
"id": "[variables('lbProbeID0')]"
},
"protocol": "tcp"
}
},
{
"name": "LBHttpRule",
"properties": {
"backendAddressPool": {
"id": "[variables('lbPoolID0')]"
},
"backendPort": "[variables('nt0fabricHttpGatewayPort')]",
"enableFloatingIP": "false",
"frontendIPConfiguration": {
"id": "[variables('lbIPConfig0')]"
},
"frontendPort": "[variables('nt0fabricHttpGatewayPort')]",
"idleTimeoutInMinutes": "5",
"probe": {
"id": "[variables('lbHttpProbeID0')]"
},
"protocol": "tcp"
}
},
{
"name": "AppPortLBRule1",
"properties": {
"backendAddressPool": {
"id": "[variables('lbPoolID0')]"
},
"backendPort": "[parameters('loadBalancedAppPort1')]",
"enableFloatingIP": "false",
"frontendIPConfiguration": {
"id": "[variables('lbIPConfig0')]"
},
"frontendPort": "[parameters('loadBalancedAppPort1')]",
"idleTimeoutInMinutes": "5",
"probe": {
"id": "[concat(variables('lbID0'),'/probes/AppPortProbe1')]"
},
"protocol": "tcp"
}
},
{
"name": "AppPortLBRule2",
"properties": {
"backendAddressPool": {
"id": "[variables('lbPoolID0')]"
},
"backendPort": "[parameters('loadBalancedAppPort2')]",
"enableFloatingIP": "false",
"frontendIPConfiguration": {
"id": "[variables('lbIPConfig0')]"
},
"frontendPort": "[parameters('loadBalancedAppPort2')]",
"idleTimeoutInMinutes": "5",
"probe": {
"id": "[concat(variables('lbID0'),'/probes/AppPortProbe2')]"
},
"protocol": "tcp"
}
},
],
"probes": [
{
"name": "FabricGatewayProbe",
"properties": {
"intervalInSeconds": 5,
"numberOfProbes": 2,
"port": "[variables('nt0fabricTcpGatewayPort')]",
"protocol": "tcp"
}
},
{
"name": "FabricHttpGatewayProbe",
"properties": {
"intervalInSeconds": 5,
"numberOfProbes": 2,
"port": "[variables('nt0fabricHttpGatewayPort')]",
"protocol": "tcp"
}
},
{
"name": "AppPortProbe1",
"properties": {
"intervalInSeconds": 5,
"numberOfProbes": 2,
"port": "[parameters('loadBalancedAppPort1')]",
"protocol": "tcp"
}
},
{
"name": "AppPortProbe2",
"properties": {
"intervalInSeconds": 5,
"numberOfProbes": 2,
"port": "[parameters('loadBalancedAppPort2')]",
"protocol": "tcp"
}
},
],
"inboundNatPools": [
{
"name": "LoadBalancerBEAddressNatPool",
"properties": {
"backendPort": "3389",
"frontendIPConfiguration": {
"id": "[variables('lbIPConfig0')]"
},
"frontendPortRangeEnd": "4500",
"frontendPortRangeStart": "3389",
"protocol": "tcp"
}
}
]
},
"tags": {
"resourceType": "Service Fabric",
"clusterName": "[parameters('clusterName')]"
}
},
{
"apiVersion": "[variables('storageApiVersion')]",
"type": "Microsoft.Storage/storageAccounts",
"name": "[variables('uniqueStringArray0')[copyIndex()]]",
"location": "[variables('computeLocation')]",
"dependsOn": [],
"properties": {},
"copy": {
"name": "storageLoop",
"count": 5
},
"kind": "Storage",
"sku": {
"name": "[parameters('storageAccountType')]"
},
"tags": {
"resourceType": "Service Fabric",
"clusterName": "[parameters('clusterName')]"
}
},
{
"apiVersion": "[variables('vmssApiVersion')]",
"type": "Microsoft.Compute/virtualMachineScaleSets",
"name": "[variables('vmNodeType0Name')]",
"location": "[variables('computeLocation')]",
"dependsOn": [
"[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]",
"[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[0])]",
"[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[1])]",
"[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[2])]",
"[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[3])]",
"[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[4])]",
"[concat('Microsoft.Network/loadBalancers/', concat('LB','-', parameters('clusterName'),'-',variables('vmNodeType0Name')))]",
"[concat('Microsoft.Storage/storageAccounts/', variables('supportLogStorageAccountName'))]",
"[concat('Microsoft.Storage/storageAccounts/', variables('applicationDiagnosticsStorageAccountName'))]"
],
"properties": {
"overprovision": "[variables('overProvision')]",
"upgradePolicy": {
"mode": "Automatic"
},
"virtualMachineProfile": {
"extensionProfile": {
"extensions": [
{
"name": "[concat('ServiceFabricNodeVmExt','_vmNodeType0Name')]",
"properties": {
"type": "ServiceFabricNode",
"autoUpgradeMinorVersion": false,
"protectedSettings": {
"StorageAccountKey1": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('supportLogStorageAccountName')),'2015-05-01-preview').key1]",
"StorageAccountKey2": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('supportLogStorageAccountName')),'2015-05-01-preview').key2]"
},
"publisher": "Microsoft.Azure.ServiceFabric",
"settings": {
"clusterEndpoint": "[reference(parameters('clusterName')).clusterEndpoint]",
"nodeTypeRef": "[variables('vmNodeType0Name')]",
"dataPath": "D:\\\\SvcFab",
"durabilityLevel": "Bronze",
"nicPrefixOverride": "10.0.0",
"certificate": {
"thumbprint": "[parameters('clusterCertificateThumbprint')]",
"x509StoreName": "[parameters('clusterCertificateStoreValue')]"
}
},
"typeHandlerVersion": "1.0"
}
},
{
"name": "[concat('VMDiagnosticsVmExt','_vmNodeType0Name')]",
"properties": {
"type": "IaaSDiagnostics",
"autoUpgradeMinorVersion": true,
"protectedSettings": {
"storageAccountName": "[variables('applicationDiagnosticsStorageAccountName')]",
"storageAccountKey": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('applicationDiagnosticsStorageAccountName')),'2015-05-01-preview').key1]",
"storageAccountEndPoint": "https://core.windows.net/"
},
"publisher": "Microsoft.Azure.Diagnostics",
"settings": {
"WadCfg": {
"DiagnosticMonitorConfiguration": {
"overallQuotaInMB": "50000",
"EtwProviders": {
"EtwEventSourceProviderConfiguration": [
{
"provider": "Microsoft-ServiceFabric-Actors",
"scheduledTransferKeywordFilter": "1",
"scheduledTransferPeriod": "PT5M",
"DefaultEvents": {
"eventDestination": "ServiceFabricReliableActorEventTable"
}
},
{
"provider": "Microsoft-ServiceFabric-Services",
"scheduledTransferPeriod": "PT5M",
"DefaultEvents": {
"eventDestination": "ServiceFabricReliableServiceEventTable"
}
},
],
"EtwManifestProviderConfiguration": [
{
"provider": "cbd93bc2-71e5-4566-b3a7-595d8eeca6e8",
"scheduledTransferLogLevelFilter": "Information",
"scheduledTransferKeywordFilter": "4611686018427387904",
"scheduledTransferPeriod": "PT5M",
"DefaultEvents": {
"eventDestination": "ServiceFabricSystemEventTable"
}
}
]
}
}
},
"StorageAccount": "[variables('applicationDiagnosticsStorageAccountName')]"
},
"typeHandlerVersion": "1.5"
}
}
]
},
"networkProfile": {
"networkInterfaceConfigurations": [
{
"name": "[concat(variables('nicName'), '-0')]",
"properties": {
"ipConfigurations": [
{
"name": "[concat(variables('nicName'),'-',0)]",
"properties": {
"loadBalancerBackendAddressPools": [
{
"id": "[variables('lbPoolID0')]"
}
],
"loadBalancerInboundNatPools": [
{
"id": "[variables('lbNatPoolID0')]"
}
],
"subnet": {
"id": "[variables('subnet0Ref')]"
}
}
}
],
"primary": true
}
}
]
},
"osProfile": {
"adminPassword": "[parameters('adminPassword')]",
"adminUsername": "[parameters('adminUsername')]",
"computernamePrefix": "[variables('vmNodeType0Name')]",
"secrets": [
{
"sourceVault": {
"id": "[parameters('sourceVaultValue')]"
},
"vaultCertificates": [
{
"certificateStore": "[parameters('clusterCertificateStorevalue')]",
"certificateUrl": "[parameters('clusterCertificateUrlValue')]"
}
]
}
]
},
"storageProfile": {
"imageReference": {
"publisher": "[parameters('vmImagePublisher')]",
"offer": "[parameters('vmImageOffer')]",
"sku": "[parameters('vmImageSku')]",
"version": "[parameters('vmImageVersion')]"
},
"osDisk": {
"vhdContainers": [
"[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[0]), variables('storageApiVersion')).primaryEndpoints.blob, variables('vmStorageAccountContainerName'))]",
"[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[1]), variables('storageApiVersion')).primaryEndpoints.blob, variables('vmStorageAccountContainerName'))]",
"[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[2]), variables('storageApiVersion')).primaryEndpoints.blob, variables('vmStorageAccountContainerName'))]",
"[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[3]), variables('storageApiVersion')).primaryEndpoints.blob, variables('vmStorageAccountContainerName'))]",
"[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[4]), variables('storageApiVersion')).primaryEndpoints.blob, variables('vmStorageAccountContainerName'))]"
],
"name": "vmssosdisk",
"caching": "ReadOnly",
"createOption": "FromImage"
}
}
}
},
"sku": {
"name": "[variables('vmNodeType0Size')]",
"capacity": "[parameters('nt0InstanceCount')]",
"tier": "Standard"
},
"tags": {
"resourceType": "Service Fabric",
"clusterName": "[parameters('clusterName')]"
}
},
{
"apiVersion": "2016-09-01",
"type": "Microsoft.ServiceFabric/clusters",
"name": "[parameters('clusterName')]",
"location": "[parameters('clusterLocation')]",
"dependsOn": [
"[concat('Microsoft.Storage/storageAccounts/', variables('supportLogStorageAccountName'))]"
],
"properties": {
"certificate": {
"thumbprint": "[parameters('clusterCertificateThumbprint')]",
"x509StoreName": "[parameters('clusterCertificateStoreValue')]"
},
"clientCertificateCommonNames": [],
"clientCertificateThumbprints": [],
"clusterState": "Default",
"diagnosticsStorageAccountConfig": {
"blobEndpoint": "[reference(concat('Microsoft.Storage/storageAccounts/', variables('supportLogStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.blob]",
"protectedAccountKeyName": "StorageAccountKey1",
"queueEndpoint": "[reference(concat('Microsoft.Storage/storageAccounts/', variables('supportLogStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.queue]",
"storageAccountName": "[variables('supportLogStorageAccountName')]",
"tableEndpoint": "[reference(concat('Microsoft.Storage/storageAccounts/', variables('supportLogStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.table]"
},
"fabricSettings": [
{
"parameters": [
{
"name": "ClusterProtectionLevel",
"value": "[parameters('clusterProtectionLevel')]"
}
],
"name": "Security"
}
],
"managementEndpoint": "[concat('https://',reference(concat(variables('lbIPName'),'-','0')).dnsSettings.fqdn,':',variables('nt0fabricHttpGatewayPort'))]",
"nodeTypes": [
{
"name": "[variables('vmNodeType0Name')]",
"applicationPorts": {
"endPort": "[variables('nt0applicationEndPort')]",
"startPort": "[variables('nt0applicationStartPort')]"
},
"clientConnectionEndpointPort": "[variables('nt0fabricTcpGatewayPort')]",
"durabilityLevel": "Bronze",
"ephemeralPorts": {
"endPort": "[variables('nt0ephemeralEndPort')]",
"startPort": "[variables('nt0ephemeralStartPort')]"
},
"httpGatewayEndpointPort": "[variables('nt0fabricHttpGatewayPort')]",
"isPrimary": true,
"vmInstanceCount": "[parameters('nt0InstanceCount')]"
}
],
"provisioningState": "Default",
"reliabilityLevel": "[parameters('nodeTypeReliabilityLevel')]",
"upgradeMode": "Automatic",
"vmImage": "Windows"
},
"tags": {
"resourceType": "Service Fabric",
"clusterName": "[parameters('clusterName')]"
}
}
],
"outputs": {
"clusterProperties": {
"value": "[reference(parameters('clusterName'))]",
"type": "object"
}
}
}
First you can test the deployment templates by issuing the test command, which if is OK prints no output.
$ResourceGroup = "sf-cluster"
$TemplateFilePath = "azuredeploy.json"
$TemplateParameterFilePath = "azuredeploy.parameters.json"
Test-AzureRmResourceGroupDeployment -ResourceGroupName $ResouceGroup -TemplateFile $TemplateFilePath -TemplateParameterFile $TemplateParameterFilePath
If everything looks good, then carry out the actual deployment
New-AzureRmResourceGroupDeployment -ResourceGroupName $ResourceGroup -TemplateFile $TemplateFilePath -TemplateParameterFile $TemplateParameterFilePath
The deployment should take less than 30 minutess.