diff --git a/deploy/arm/eShopOnAzure.Deploy.sln b/deploy/arm/eShopOnAzure.Deploy.sln
new file mode 100644
index 000000000..6fb65821a
--- /dev/null
+++ b/deploy/arm/eShopOnAzure.Deploy.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26430.6
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{151D2E53-A2C4-4D7D-83FE-D05416EBD58E}") = "eShopOnAzure.Deploy", "eShopOnAzure.Deploy\eShopOnAzure.Deploy.deployproj", "{642B3F2E-3011-4B1A-8D22-D35C11C44F05}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {642B3F2E-3011-4B1A-8D22-D35C11C44F05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {642B3F2E-3011-4B1A-8D22-D35C11C44F05}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {642B3F2E-3011-4B1A-8D22-D35C11C44F05}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {642B3F2E-3011-4B1A-8D22-D35C11C44F05}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/deploy/arm/eShopOnAzure.Deploy/Deploy-AzureResourceGroup.ps1 b/deploy/arm/eShopOnAzure.Deploy/Deploy-AzureResourceGroup.ps1
new file mode 100644
index 000000000..cf119eea6
--- /dev/null
+++ b/deploy/arm/eShopOnAzure.Deploy/Deploy-AzureResourceGroup.ps1
@@ -0,0 +1,120 @@
+#Requires -Version 3.0
+#Requires -Module AzureRM.Resources
+#Requires -Module Azure.Storage
+
+Param(
+ [string] [Parameter(Mandatory=$true)] $ResourceGroupLocation,
+ [string] $ResourceGroupName = 'eShopOnAzure.Deploy',
+ [switch] $UploadArtifacts,
+ [string] $StorageAccountName,
+ [string] $StorageContainerName = $ResourceGroupName.ToLowerInvariant() + '-stageartifacts',
+ [string] $TemplateFile = 'azuredeploy.json',
+ [string] $TemplateParametersFile = 'azuredeploy.parameters.json',
+ [string] $ArtifactStagingDirectory = '.',
+ [string] $DSCSourceFolder = 'DSC',
+ [switch] $ValidateOnly
+)
+
+try {
+ [Microsoft.Azure.Common.Authentication.AzureSession]::ClientFactory.AddUserAgent("VSAzureTools-$UI$($host.name)".replace(' ','_'), '3.0.0')
+} catch { }
+
+$ErrorActionPreference = 'Stop'
+Set-StrictMode -Version 3
+
+function Format-ValidationOutput {
+ param ($ValidationOutput, [int] $Depth = 0)
+ Set-StrictMode -Off
+ return @($ValidationOutput | Where-Object { $_ -ne $null } | ForEach-Object { @(' ' * $Depth + ': ' + $_.Message) + @(Format-ValidationOutput @($_.Details) ($Depth + 1)) })
+}
+
+$OptionalParameters = New-Object -TypeName Hashtable
+$TemplateFile = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($PSScriptRoot, $TemplateFile))
+$TemplateParametersFile = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($PSScriptRoot, $TemplateParametersFile))
+
+if ($UploadArtifacts) {
+ # Convert relative paths to absolute paths if needed
+ $ArtifactStagingDirectory = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($PSScriptRoot, $ArtifactStagingDirectory))
+ $DSCSourceFolder = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($PSScriptRoot, $DSCSourceFolder))
+
+ # Parse the parameter file and update the values of artifacts location and artifacts location SAS token if they are present
+ $JsonParameters = Get-Content $TemplateParametersFile -Raw | ConvertFrom-Json
+ if (($JsonParameters | Get-Member -Type NoteProperty 'parameters') -ne $null) {
+ $JsonParameters = $JsonParameters.parameters
+ }
+ $ArtifactsLocationName = '_artifactsLocation'
+ $ArtifactsLocationSasTokenName = '_artifactsLocationSasToken'
+ $OptionalParameters[$ArtifactsLocationName] = $JsonParameters | Select -Expand $ArtifactsLocationName -ErrorAction Ignore | Select -Expand 'value' -ErrorAction Ignore
+ $OptionalParameters[$ArtifactsLocationSasTokenName] = $JsonParameters | Select -Expand $ArtifactsLocationSasTokenName -ErrorAction Ignore | Select -Expand 'value' -ErrorAction Ignore
+
+ # Create DSC configuration archive
+ if (Test-Path $DSCSourceFolder) {
+ $DSCSourceFilePaths = @(Get-ChildItem $DSCSourceFolder -File -Filter '*.ps1' | ForEach-Object -Process {$_.FullName})
+ foreach ($DSCSourceFilePath in $DSCSourceFilePaths) {
+ $DSCArchiveFilePath = $DSCSourceFilePath.Substring(0, $DSCSourceFilePath.Length - 4) + '.zip'
+ Publish-AzureRmVMDscConfiguration $DSCSourceFilePath -OutputArchivePath $DSCArchiveFilePath -Force -Verbose
+ }
+ }
+
+ # Create a storage account name if none was provided
+ if ($StorageAccountName -eq '') {
+ $StorageAccountName = 'stage' + ((Get-AzureRmContext).Subscription.SubscriptionId).Replace('-', '').substring(0, 19)
+ }
+
+ $StorageAccount = (Get-AzureRmStorageAccount | Where-Object{$_.StorageAccountName -eq $StorageAccountName})
+
+ # Create the storage account if it doesn't already exist
+ if ($StorageAccount -eq $null) {
+ $StorageResourceGroupName = 'ARM_Deploy_Staging'
+ New-AzureRmResourceGroup -Location "$ResourceGroupLocation" -Name $StorageResourceGroupName -Force
+ $StorageAccount = New-AzureRmStorageAccount -StorageAccountName $StorageAccountName -Type 'Standard_LRS' -ResourceGroupName $StorageResourceGroupName -Location "$ResourceGroupLocation"
+ }
+
+ # Generate the value for artifacts location if it is not provided in the parameter file
+ if ($OptionalParameters[$ArtifactsLocationName] -eq $null) {
+ $OptionalParameters[$ArtifactsLocationName] = $StorageAccount.Context.BlobEndPoint + $StorageContainerName
+ }
+
+ # Copy files from the local storage staging location to the storage account container
+ New-AzureStorageContainer -Name $StorageContainerName -Context $StorageAccount.Context -ErrorAction SilentlyContinue *>&1
+
+ $ArtifactFilePaths = Get-ChildItem $ArtifactStagingDirectory -Recurse -File | ForEach-Object -Process {$_.FullName}
+ foreach ($SourcePath in $ArtifactFilePaths) {
+ Set-AzureStorageBlobContent -File $SourcePath -Blob $SourcePath.Substring($ArtifactStagingDirectory.length + 1) `
+ -Container $StorageContainerName -Context $StorageAccount.Context -Force
+ }
+
+ # Generate a 4 hour SAS token for the artifacts location if one was not provided in the parameters file
+ if ($OptionalParameters[$ArtifactsLocationSasTokenName] -eq $null) {
+ $OptionalParameters[$ArtifactsLocationSasTokenName] = ConvertTo-SecureString -AsPlainText -Force `
+ (New-AzureStorageContainerSASToken -Container $StorageContainerName -Context $StorageAccount.Context -Permission r -ExpiryTime (Get-Date).AddHours(4))
+ }
+}
+
+# Create or update the resource group using the specified template file and template parameters file
+New-AzureRmResourceGroup -Name $ResourceGroupName -Location $ResourceGroupLocation -Verbose -Force
+
+if ($ValidateOnly) {
+ $ErrorMessages = Format-ValidationOutput (Test-AzureRmResourceGroupDeployment -ResourceGroupName $ResourceGroupName `
+ -TemplateFile $TemplateFile `
+ -TemplateParameterFile $TemplateParametersFile `
+ @OptionalParameters)
+ if ($ErrorMessages) {
+ Write-Output '', 'Validation returned the following errors:', @($ErrorMessages), '', 'Template is invalid.'
+ }
+ else {
+ Write-Output '', 'Template is valid.'
+ }
+}
+else {
+ New-AzureRmResourceGroupDeployment -Name ((Get-ChildItem $TemplateFile).BaseName + '-' + ((Get-Date).ToUniversalTime()).ToString('MMdd-HHmm')) `
+ -ResourceGroupName $ResourceGroupName `
+ -TemplateFile $TemplateFile `
+ -TemplateParameterFile $TemplateParametersFile `
+ @OptionalParameters `
+ -Force -Verbose `
+ -ErrorVariable ErrorMessages
+ if ($ErrorMessages) {
+ Write-Output '', 'Template deployment returned the following errors:', @(@($ErrorMessages) | ForEach-Object { $_.Exception.Message.TrimEnd("`r`n") })
+ }
+}
\ No newline at end of file
diff --git a/deploy/arm/eShopOnAzure.Deploy/Deployment.targets b/deploy/arm/eShopOnAzure.Deploy/Deployment.targets
new file mode 100644
index 000000000..0d792ec66
--- /dev/null
+++ b/deploy/arm/eShopOnAzure.Deploy/Deployment.targets
@@ -0,0 +1,123 @@
+
+
+
+ Debug
+ AnyCPU
+ bin\$(Configuration)\
+ false
+ true
+ false
+ None
+ obj\
+ $(BaseIntermediateOutputPath)\
+ $(BaseIntermediateOutputPath)$(Configuration)\
+ $(IntermediateOutputPath)ProjectReferences
+ $(ProjectReferencesOutputPath)\
+ true
+
+
+
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+ Never
+
+
+ false
+ Build
+
+
+
+
+
+
+
+ _GetDeploymentProjectContent;
+ _CalculateContentOutputRelativePaths;
+ _GetReferencedProjectsOutput;
+ _CalculateArtifactStagingDirectory;
+ _CopyOutputToArtifactStagingDirectory;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Configuration=$(Configuration);Platform=$(Platform)
+
+
+
+
+
+
+ $([System.IO.Path]::GetFileNameWithoutExtension('%(ProjectReference.Identity)'))
+
+
+
+
+
+
+ $(OutDir)
+ $(OutputPath)
+ $(ArtifactStagingDirectory)\
+ $(ArtifactStagingDirectory)staging\
+ $(Build_StagingDirectory)
+
+
+
+
+
+
+ <_OriginalIdentity>%(DeploymentProjectContentOutput.Identity)
+ <_RelativePath>$(_OriginalIdentity.Replace('$(MSBuildProjectDirectory)', ''))
+
+
+
+
+ $(_RelativePath)
+
+
+
+
+
+
+
+
+ PrepareForRun
+
+
+
+
+
+
+
+
+
+
+
diff --git a/deploy/arm/eShopOnAzure.Deploy/eShopOnAzure.Deploy.deployproj b/deploy/arm/eShopOnAzure.Deploy/eShopOnAzure.Deploy.deployproj
new file mode 100644
index 000000000..b44305d1e
--- /dev/null
+++ b/deploy/arm/eShopOnAzure.Deploy/eShopOnAzure.Deploy.deployproj
@@ -0,0 +1,38 @@
+
+
+
+
+ Debug
+ AnyCPU
+
+
+ Release
+ AnyCPU
+
+
+
+ 642b3f2e-3011-4b1a-8d22-d35c11c44f05
+
+
+ Deployment
+ 1.0
+
+
+
+
+
+
+
+
+
+
+ False
+
+
+
+ Never
+
+
+
+
+
\ No newline at end of file
diff --git a/deploy/arm/eShopOnAzure.Deploy/sqldeploy.json b/deploy/arm/eShopOnAzure.Deploy/sqldeploy.json
new file mode 100644
index 000000000..c4b9dca20
--- /dev/null
+++ b/deploy/arm/eShopOnAzure.Deploy/sqldeploy.json
@@ -0,0 +1,103 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "sql_server": {
+ "type": "object"
+ },
+ "suffix": {
+ "type": "string"
+ }
+ },
+ "variables": {
+ "sql_server_name": "[concat(parameters('sql_server').name, '-', parameters('suffix'))]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Sql/servers",
+ "name": "[variables('sql_server_name')]",
+ "apiVersion": "2014-04-01-preview",
+ "location": "[resourceGroup().location]",
+ "properties": {
+ "administratorLogin": "[parameters('sql_server').admin]",
+ "administratorLoginPassword": "[parameters('sql_server').adminpwd]",
+ "version": "12.0"
+ },
+ "resources": [
+ {
+ "type": "databases",
+ "name": "[parameters('sql_server').dbs.ordering]",
+ "apiVersion": "2014-04-01-preview",
+ "location": "[resourceGroup().location]",
+ "properties": {
+ "edition": "Standard",
+ "collation": "SQL_Latin1_General_CP1_CI_AS",
+ "maxSizeBytes": "1073741824",
+ "requestedServiceObjectiveName": "S1"
+ },
+ "dependsOn": [
+ "[concat('Microsoft.Sql/servers/', variables('sql_server_name'))]"
+ ]
+ },
+ {
+ "type": "databases",
+ "name": "[parameters('sql_server').dbs.identity]",
+ "apiVersion": "2014-04-01-preview",
+ "location": "[resourceGroup().location]",
+ "properties": {
+ "edition": "Standard",
+ "collation": "SQL_Latin1_General_CP1_CI_AS",
+ "maxSizeBytes": "1073741824",
+ "requestedServiceObjectiveName": "S1"
+ },
+ "dependsOn": [
+ "[concat('Microsoft.Sql/servers/', variables('sql_server_name'))]"
+ ]
+ },
+ {
+ "type": "databases",
+ "name": "[parameters('sql_server').dbs.catalog]",
+ "apiVersion": "2014-04-01-preview",
+ "location": "[resourceGroup().location]",
+ "properties": {
+ "edition": "Standard",
+ "collation": "SQL_Latin1_General_CP1_CI_AS",
+ "maxSizeBytes": "1073741824",
+ "requestedServiceObjectiveName": "S1"
+ },
+ "dependsOn": [
+ "[concat('Microsoft.Sql/servers/', variables('sql_server_name'))]"
+ ]
+ },
+ {
+ "type": "firewallrules",
+ "name": "AllowAllWindowsAzureIps",
+ "apiVersion": "2014-04-01-preview",
+ "location": "[resourceGroup().location]",
+ "properties": {
+ "startIpAddress": "0.0.0.0",
+ "endIpAddress": "0.0.0.0"
+ },
+ "dependsOn": [
+ "[concat('Microsoft.Sql/servers/', variables('sql_server_name'))]"
+ ]
+ },
+ {
+ "type": "firewallrules",
+ "name": "AllConnectionsAllowed",
+ "apiVersion": "2014-04-01-preview",
+ "location": "[resourceGroup().location]",
+ "properties": {
+ "startIpAddress": "0.0.0.0",
+ "endIpAddress": "255.255.255.255"
+ },
+ "dependsOn": [
+ "[concat('Microsoft.Sql/servers/', variables('sql_server_name'))]"
+ ]
+ }
+ ]
+ }
+ ],
+ "outputs": {
+ }
+}
diff --git a/deploy/arm/eShopOnAzure.Deploy/sqldeploy.parameters.json b/deploy/arm/eShopOnAzure.Deploy/sqldeploy.parameters.json
new file mode 100644
index 000000000..5b0dfdbae
--- /dev/null
+++ b/deploy/arm/eShopOnAzure.Deploy/sqldeploy.parameters.json
@@ -0,0 +1,21 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "sql_server": {
+ "value": {
+ "name": "eshop-sqlsrv",
+ "admin": "eshop",
+ "adminpwd": "Pass@word",
+ "dbs": {
+ "ordering": "orderingdb",
+ "identity": "identitydb",
+ "catalog": "catalogdb"
+ }
+ }
+ },
+ "suffix": {
+ "value": "edu"
+ }
+ }
+}
diff --git a/deploy/az/linux-vm/create-resources.cmd b/deploy/az/linux-vm/create-resources.cmd
deleted file mode 100644
index c8e317b2d..000000000
--- a/deploy/az/linux-vm/create-resources.cmd
+++ /dev/null
@@ -1,5 +0,0 @@
-REM az group create --name eShopOnAzureDev --location westus
-
-az group deployment create --resource-group eShopOnAzureDev --parameters @mvparams.json ^
- --template-uri https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/docker-simple-on-ubuntu/azuredeploy.json
-
diff --git a/deploy/az/vms/linux-vm/azuredeploy.json b/deploy/az/vms/linux-vm/azuredeploy.json
new file mode 100644
index 000000000..5b4778ebe
--- /dev/null
+++ b/deploy/az/vms/linux-vm/azuredeploy.json
@@ -0,0 +1,199 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "newStorageAccountName": {
+ "type": "string",
+ "metadata": {
+ "description": "Unique DNS Name for the Storage Account where the Virtual Machine's disks will be placed."
+ }
+ },
+ "adminUsername": {
+ "type": "string",
+ "metadata": {
+ "description": "Username for the Virtual Machine."
+ }
+ },
+ "adminPassword": {
+ "type": "securestring",
+ "metadata": {
+ "description": "Password for the Virtual Machine."
+ }
+ },
+ "dnsNameForPublicIP": {
+ "type": "string",
+ "metadata": {
+ "description": "Unique DNS Name for the Public IP used to access the Virtual Machine."
+ }
+ },
+ "ubuntuOSVersion": {
+ "type": "string",
+ "defaultValue": "14.04.4-LTS",
+ "metadata": {
+ "description": "The Ubuntu version for deploying the Docker containers. This will pick a fully patched image of this given Ubuntu version. Allowed values: 14.04.4-LTS, 15.10, 16.04.0-LTS"
+ },
+ "allowedValues": [
+ "14.04.4-LTS",
+ "15.10",
+ "16.04.0-LTS"
+ ]
+ },
+ "VMName": {
+ "type": "string",
+ "metadata": {
+ "description": "Name of VM in Azure"
+ }
+ }
+ },
+ "variables": {
+ "newStorageAccountName": "[take(concat(parameters('newStorageAccountName'), uniqueString(resourceGroup().id)), 23)]",
+ "dnsNameForPublicIP": "[concat(parameters('dnsNameForPublicIP'), uniqueString(resourceGroup().id))]",
+ "imagePublisher": "Canonical",
+ "imageOffer": "UbuntuServer",
+ "OSDiskName": "osdiskfordockersimple",
+ "nicName": "myVMNicD",
+ "extensionName": "DockerExtension",
+ "addressPrefix": "10.0.0.0/16",
+ "subnetName": "Subnet",
+ "subnetPrefix": "10.0.0.0/24",
+ "storageAccountType": "Standard_LRS",
+ "publicIPAddressName": "myPublicIPD",
+ "publicIPAddressType": "Dynamic",
+ "vmStorageAccountContainerName": "vhds",
+ "vmName": "[parameters('VMName')]",
+ "vmSize": "Standard_F1",
+ "virtualNetworkName": "MyVNETD",
+ "vnetID": "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]",
+ "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Storage/storageAccounts",
+ "name": "[variables('newStorageAccountName')]",
+ "apiVersion": "2015-05-01-preview",
+ "location": "[resourceGroup().location]",
+ "properties": {
+ "accountType": "[variables('storageAccountType')]"
+ }
+ },
+ {
+ "apiVersion": "2015-05-01-preview",
+ "type": "Microsoft.Network/publicIPAddresses",
+ "name": "[variables('publicIPAddressName')]",
+ "location": "[resourceGroup().location]",
+ "properties": {
+ "publicIPAllocationMethod": "[variables('publicIPAddressType')]",
+ "dnsSettings": {
+ "domainNameLabel": "[variables('dnsNameForPublicIP')]"
+ }
+ }
+ },
+ {
+ "apiVersion": "2015-05-01-preview",
+ "type": "Microsoft.Network/virtualNetworks",
+ "name": "[variables('virtualNetworkName')]",
+ "location": "[resourceGroup().location]",
+ "properties": {
+ "addressSpace": {
+ "addressPrefixes": [
+ "[variables('addressPrefix')]"
+ ]
+ },
+ "subnets": [
+ {
+ "name": "[variables('subnetName')]",
+ "properties": {
+ "addressPrefix": "[variables('subnetPrefix')]"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "apiVersion": "2015-05-01-preview",
+ "type": "Microsoft.Network/networkInterfaces",
+ "name": "[variables('nicName')]",
+ "location": "[resourceGroup().location]",
+ "dependsOn": [
+ "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]",
+ "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]"
+ ],
+ "properties": {
+ "ipConfigurations": [
+ {
+ "name": "ipconfig1",
+ "properties": {
+ "privateIPAllocationMethod": "Dynamic",
+ "publicIPAddress": {
+ "id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]"
+ },
+ "subnet": {
+ "id": "[variables('subnetRef')]"
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "apiVersion": "2015-05-01-preview",
+ "type": "Microsoft.Compute/virtualMachines",
+ "name": "[variables('vmName')]",
+ "location": "[resourceGroup().location]",
+ "dependsOn": [
+ "[concat('Microsoft.Storage/storageAccounts/', variables('newStorageAccountName'))]",
+ "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]"
+ ],
+ "properties": {
+ "hardwareProfile": {
+ "vmSize": "[variables('vmSize')]"
+ },
+ "osProfile": {
+ "computerName": "[variables('vmName')]",
+ "adminUsername": "[parameters('adminUsername')]",
+ "adminPassword": "[parameters('adminPassword')]"
+ },
+ "storageProfile": {
+ "imageReference": {
+ "publisher": "[variables('imagePublisher')]",
+ "offer": "[variables('imageOffer')]",
+ "sku": "[parameters('ubuntuOSVersion')]",
+ "version": "latest"
+ },
+ "osDisk": {
+ "name": "osdisk1",
+ "vhd": {
+ "uri": "[concat('http://',variables('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/',variables('OSDiskName'),'.vhd')]"
+ },
+ "caching": "ReadWrite",
+ "createOption": "FromImage"
+ }
+ },
+ "networkProfile": {
+ "networkInterfaces": [
+ {
+ "id": "[resourceId('Microsoft.Network/networkInterfaces',variables('nicName'))]"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "Microsoft.Compute/virtualMachines/extensions",
+ "name": "[concat(variables('vmName'),'/', variables('extensionName'))]",
+ "apiVersion": "2015-05-01-preview",
+ "location": "[resourceGroup().location]",
+ "dependsOn": [
+ "[concat('Microsoft.Compute/virtualMachines/', variables('vmName'))]"
+ ],
+ "properties": {
+ "publisher": "Microsoft.Azure.Extensions",
+ "type": "DockerExtension",
+ "typeHandlerVersion": "1.0",
+ "autoUpgradeMinorVersion": true,
+ "settings": { }
+ }
+ }
+ ]
+}
+
diff --git a/deploy/az/vms/linux-vm/create-resources.cmd b/deploy/az/vms/linux-vm/create-resources.cmd
new file mode 100644
index 000000000..82ac4da6d
--- /dev/null
+++ b/deploy/az/vms/linux-vm/create-resources.cmd
@@ -0,0 +1,21 @@
+@echo off
+if %1.==. GOTO error
+if NOT %2.==-c. GOTO createvm
+if %3.==. GOTO error
+echo Creating resource group %1 in '%3'
+call az group create --name %1 --location %3
+:createvm
+echo Creating VM in resource group %1
+call az group deployment create --resource-group %1 --parameters @mvparams.json --template-file azuredeploy.json
+GOTO end
+:error
+echo.
+echo Usage:
+echo create-resources resource-group-name [-c location]
+echo resource-grop-name: Name of the resource group to use or create
+echo -c: If appears means that resource group must be created. If -c is specified, must use enter location
+echo.
+echo Examples:
+echo create-resources testgroup (Creates VM in a existing testgroup resource group)
+echo create-resources newgroup -c westus (Creates the VM in a NEW resource group named newgroup in the westus location)
+:end
diff --git a/deploy/az/linux-vm/mvparams.json b/deploy/az/vms/linux-vm/mvparams.json
similarity index 63%
rename from deploy/az/linux-vm/mvparams.json
rename to deploy/az/vms/linux-vm/mvparams.json
index c80c82e6c..d34dfd1d9 100644
--- a/deploy/az/linux-vm/mvparams.json
+++ b/deploy/az/vms/linux-vm/mvparams.json
@@ -2,5 +2,6 @@
"newStorageAccountName": { "value": "eshopsrvmvstorage" },
"adminUsername": { "value": "eshop" },
"adminPassword": { "value": "Pass@word" },
- "dnsNameForPublicIP": { "value": "eshop-srv" }
+ "dnsNameForPublicIP": { "value": "eshop-srv" },
+ "VMName": {"value": "MyDockerVM2"}
}
diff --git a/deploy/az/vms/readme.md b/deploy/az/vms/readme.md
new file mode 100644
index 000000000..a2e9c42b7
--- /dev/null
+++ b/deploy/az/vms/readme.md
@@ -0,0 +1,54 @@
+# Deploy a VM to run the services
+
+Follow these instructions to deploy a Linux-based VM with the Docker Host installed, or a VM with Windows Server 2016 plus
+windows containers and Docker Daemon.
+
+You can use this machine to installthe microservices and having a "development" environment (useful to develop and test the client apps).
+
+Please note that this deployment is not a production deployment. In a production-based scenario, you should deploy all containers in ACS.
+
+## Create the VM
+
+Ensure you are logged in the desired subscription (use `az login` and `az account set` if needed. Refer to [this article](https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli) for more details.
+
+Go to `linux-vm` or `win-vm` folder (based on if you want a Linux or Windows VM). Then:
+
+1. Edit the file `mvparams.json` with your desired values
+2. Run the file `create-resources.cmd` from command-line to create the VM.
+
+**Note:** To avoid errors, ARM template used (`azuredeploy.json`), generates unique names for:
+
+1. VM used storage
+2. Public DNS
+
+Those public names are based on the parameters set in `mvparams.json` file.
+
+### The mvparams.json file
+
+This file contains the minimum set of parameters needed by the ARM template to deploy the VM. ARM template accepts some other parameters (set with
+default values). Look the template for more info.
+
+The parameters defined in this file are:
+
+1. `newStorageAccountName`: Name of the storage created for the VM. To ensure uniqueness a unique suffix will be added to this value.
+2. `adminUsername`: Admin login
+3. `adminPassword`: Admin password
+4. `dnsNameForPublicIP`: DNS of the VM. To ensure uniqueness a unique suffix will be added to this value.
+5. `VMName`: Name of the VM inside Azure
+
+## Finding the IP and DNS of the VM
+
+To find the IP and FQDN of the VM you can type `az vm list --resource-group --output table --show-details` (where resourcegroup is the
+name of the resourcegroup where you created the VM). This command will generate output like:
+
+```
+Name ResourceGroup PowerState PublicIps Fqdns Location
+---------- --------------- ------------ ------------- ------------------------------------------------ ----------
+MyDockerVM MyResourceGroup VM running xx.xx.xxx.xxx eshop-srvxxxxxxxxxxxxx.westus.cloudapp.azure.com westus
+```
+
+You can use this information to connect your new VM.
+
+## Deploy services in the VM
+
+We are providing public images of the services in DockerHub (https://hub.docker.com/u/eshop/).
diff --git a/deploy/az/win-vm/azuredeploy.json b/deploy/az/vms/win-vm/azuredeploy.json
similarity index 93%
rename from deploy/az/win-vm/azuredeploy.json
rename to deploy/az/vms/win-vm/azuredeploy.json
index 89bf54785..78bebdfef 100644
--- a/deploy/az/win-vm/azuredeploy.json
+++ b/deploy/az/vms/win-vm/azuredeploy.json
@@ -43,10 +43,12 @@
"metadata": {
"description": "VM Size"
}
- }
+ }
},
"variables": {
+ "newStorageAccountName": "[take(concat(parameters('newStorageAccountName'), uniqueString(resourceGroup().id)), 23)]",
+ "dnsNameForPublicIP": "[concat(parameters('dnsNameForPublicIP'), uniqueString(resourceGroup().id))]",
"windowsOSVersion": "2016-Datacenter",
"imagePublisher": "MicrosoftWindowsServer",
"imageOffer": "WindowsServer",
@@ -66,7 +68,6 @@
"subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]"
},
"resources": [
-
{
"type": "Microsoft.Network/networkSecurityGroups",
"name": "[variables('networkSecurityGroupName')]",
@@ -125,7 +126,7 @@
{
"type": "Microsoft.Storage/storageAccounts",
- "name": "[parameters('newStorageAccountName')]",
+ "name": "[variables('newStorageAccountName')]",
"apiVersion": "[variables('apiVersion')]",
"location": "[resourceGroup().location]",
"tags": {
@@ -147,7 +148,7 @@
"properties": {
"publicIPAllocationMethod": "[variables('publicIPAddressType')]",
"dnsSettings": {
- "domainNameLabel": "[tolower(parameters('dnsNameForPublicIP'))]"
+ "domainNameLabel": "[tolower(variables('dnsNameForPublicIP'))]"
}
}
},
@@ -222,7 +223,7 @@
"displayName": "VirtualMachine"
},
"dependsOn": [
- "[concat('Microsoft.Storage/storageAccounts/', parameters('newStorageAccountName'))]",
+ "[concat('Microsoft.Storage/storageAccounts/', variables('newStorageAccountName'))]",
"[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]"
],
"properties": {
@@ -244,7 +245,7 @@
"osDisk": {
"name": "osdisk",
"vhd": {
- "uri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/', parameters('newStorageAccountName')), variables('apiVersion')).primaryEndpoints.blob, variables('vmStorageAccountContainerName'),'/',variables('OSDiskName'),'.vhd')]"
+ "uri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('newStorageAccountName')), variables('apiVersion')).primaryEndpoints.blob, variables('vmStorageAccountContainerName'),'/',variables('OSDiskName'),'.vhd')]"
},
"caching": "ReadWrite",
"createOption": "FromImage"
diff --git a/deploy/az/vms/win-vm/create-resources.cmd b/deploy/az/vms/win-vm/create-resources.cmd
new file mode 100644
index 000000000..07ac2a2da
--- /dev/null
+++ b/deploy/az/vms/win-vm/create-resources.cmd
@@ -0,0 +1,15 @@
+if %1.==. GOTO error
+if %2.!=-c. GOTO createvm
+if %3.==. GOTO error
+az group create --name %1 --location %3
+createvm:
+az group deployment create --resource-group %1 --parameters @mvparams.json --template-file azuredeploy.json
+GOTO end
+error:
+@echo Usage: create-resources [-c location]
+@echo : Name of the resource group to use or create
+@echo -c: If appears means that resource group must be created. If -c is specified, must use enter location
+@echo Examples:
+@echo create-resources testgroup (Creates VM in a existing testgroup resource group)
+@echo create-resources newgroup -c westus (Creates the VM in a NEW resource group named newgroup in the westus location)
+end:
diff --git a/deploy/az/win-vm/mvparams.json b/deploy/az/vms/win-vm/mvparams.json
similarity index 100%
rename from deploy/az/win-vm/mvparams.json
rename to deploy/az/vms/win-vm/mvparams.json
diff --git a/deploy/az/win-vm/create-resources.cmd b/deploy/az/win-vm/create-resources.cmd
deleted file mode 100644
index b35de9431..000000000
--- a/deploy/az/win-vm/create-resources.cmd
+++ /dev/null
@@ -1,3 +0,0 @@
-REM az group create --name eShopOnAzureDevWin --location westus
-az group deployment create --resource-group eShopOnAzureDevWin --parameters @mvparams.json --template-file azuredeploy.json
-
diff --git a/deploy/readme.md b/deploy/readme.md
index 4fd772049..66efea64b 100644
--- a/deploy/readme.md
+++ b/deploy/readme.md
@@ -4,11 +4,17 @@
1. [Azure CLI 2.0 Installed](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli)
2. Azure subscription created
+Login into your azure subscription by typing `az login` (note that you maybe need to use `az account set` to set the subscription to use). Refer to [this article](https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli) for more details
+
## Deploying using CLI
-1. Run `az login` to login into your Azure subscription (note that you maybe need to use `az account set` to set the subscription to use)
-2. Edit the file `mvparams.json` with your desired values
-3. Run the file `create-resources.cmd` from command-line to create the Linux-based VM with Docker installed
+## Deploying Virtual machines to host the services
+
+1. [Deploying a Linux VM or Windows Server 2016 to run a single-development environment](az/vms/readme.md)
+
+## Deploying Azure resources used by the services
+
+1. [Deploying SQL Server and databases](arm/sql-server.md)