Import a database using AzureRM Powershell - azure

There is a document named Import a BACPAC file to create a new Azure SQL database using PowerShell that covers how to import a bacpac file into SQL server under ASM.
Is there a way to import a bacpac file into an Azure SQL Server using Azure Resource Management cmdlets.
Following on from #juvchan answer I have been trying to get the following to work.
$update = #{
"operationMode" = "Import"
"storageKey"= "Key"
"storageKeyType" = "Primary"
"administratorLogin"= "adminlogin"
"administratorLoginPassword"= "adminpassword"
"storageUri"= "https://example.blob.core.windows.net/sql/exampleIOSQL-2016-1-23-12-26.bacpac"
}
New-AzureRmResource -ResourceGroupName "resourcegroupname" `
-ResourceType "Microsoft.Sql/servers" `
-Name "sqldbsvr" `
-PropertyObject $update `
-ApiVersion 2015-08-01 `
-Force -Location "westeurope"
Unfortunately I can't get anything but this very helpful error message -
New-AzureRmResource : {"code":"","message":"An error occurred while processing this request.","target":null,"details":[],"innererror":[]}

At current time, the latest Microsoft Azure PowerShell - January 2016 (version 1.1)'s Azure RM module does not have any cmdlets which
can support Azure SQL database import like the Azure Service Management's cmdlet i.e. Start-AzureSqlDatabaseImport
However, there is a workaround which can achieve this in the Azure Resource Manager (ARM) context.
The workaround is to do a Azure Resource Group template deployment with a user-defined ARM template which include the database import resource type.
The proposed workaround consist of a sample PowerShell script, a sample ARM template json and a sample ARM Template parameters json as shown below:
The PowerShell sample code is as below:
Login-AzureRmAccount
$tenantId = "your_tenant_id"
$subscriptionId = "your_subscription_id"
$rgName = "your_rg_name"
$location = "your_location"
$templateFile = "YourARMTemplate.json"
$templateParamFile = "YourARMTemplate.Parameters.json"
Set-AzureRmContext -SubscriptionId $subscriptionId -TenantId $tenantId
New-AzureRmResourceGroup -Location $location -Name $rgName -Force
$deployment = New-AzureRmResourceGroupDeployment -ResourceGroupName $rgName -TemplateFile $templateFile -TemplateParameterFile $templateParamFile -Mode Incremental -Force
The sample ARM template json for Azure SQL database import is as below:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"variables": {
"dbApiVersion": "2014-04-01-preview",
"resourceGroupLocation": "[resourceGroup().location]",
"dbServerNameTidy": "[toLower(trim(parameters('dbServerName')))]",
"masterDbNameTidy": "[toLower(trim(parameters('masterDbName')))]"
},
"parameters": {
"dbServerName": {
"type": "string"
},
"dbLogin": {
"type": "string"
},
"dbPassword": {
"type": "string"
},
"dbServerVersion": {
"type": "string",
"defaultValue": "12.0"
},
"dbCollation": {
"type": "string",
"defaultValue": "SQL_Latin1_General_CP1_CI_AS"
},
"dbEdition": {
"type": "string",
"defaultValue": "Standard"
},
"dbMaxSize": {
"type": "string",
"defaultValue": "10737418240"
},
"dbServiceObjectiveLevel": {
"type": "string",
"defaultValue": "455330E1-00CD-488B-B5FA-177C226F28B7"
},
"bacpacStorageKey": {
"type": "string"
},
"masterDbName": {
"type": "string"
},
"masterBacpacUrl": {
"type": "string"
},
},
"resources": [
{
"type": "Microsoft.Sql/servers",
"apiVersion": "[variables('dbApiVersion')]",
"properties": {
"administratorLogin": "[parameters('dbLogin')]",
"administratorLoginPassword": "[parameters('dbPassword')]",
"version": "[parameters('dbServerVersion')]"
},
"name": "[variables('dbServerNameTidy')]",
"location": "[variables('resourceGroupLocation')]",
"resources": [
{
"type": "firewallrules",
"apiVersion": "[variables('dbApiVersion')]",
"properties": {
"endIpAddress": "0.0.0.0",
"startIpAddress": "0.0.0.0"
},
"name": "AllowAllWindowsAzureIps",
"dependsOn": [
"[resourceId('Microsoft.Sql/servers', variables('dbServerNameTidy'))]"
]
},
{
"type": "databases",
"apiVersion": "[variables('dbApiVersion')]",
"properties": {
"edition": "[parameters('dbEdition')]",
"collation": "[parameters('dbCollation')]",
"maxSizeBytes": "[parameters('dbMaxSize')]",
"requestedServiceObjectiveId": "[parameters('dbServiceObjectiveLevel')]"
},
"name": "[variables('webDbNameTidy')]",
"location": "[variables('resourceGroupLocation')]",
"dependsOn": [
"[resourceId('Microsoft.Sql/servers', variables('dbServerNameTidy'))]"
],
"resources": [
{
"type": "extensions",
"apiVersion": "[variables('dbApiVersion')]",
"properties": {
"operationMode": "Import",
"storageKey": "[parameters('bacpacStorageKey')]",
"storageKeyType": "Primary",
"administratorLogin": "[parameters('dbLogin')]",
"administratorLoginPassword": "[parameters('dbPassword')]",
"storageUri": "[parameters('masterBacpacUrl')]"
},
"name": "Import",
"dependsOn": [
"[resourceId('Microsoft.Sql/servers/databases', variables('dbServerNameTidy'), variables('masterDbNameTidy'))]"
]
}
]
}
]
}
]
}
The sample ARM template parameters json for Azure SQL database import is as below:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"dbServerName": {
"value": "<your DB Server Name>"
},
"dbLogin": {
"value": "<Your DB server login name>"
},
"dbPassword": {
"value": "<Your DB server login password>"
},
"bacpacStorageKey": {
"value": "<Your Azure Storage Account Primary key which stores the bacpac blob>"
},
"masterDbName": {
"value": "<your Azure Sql Db name>"
},
"masterBacpacUrl": {
"value": "<Your Azure storage account Bacpac blob file full Url>"
}
}
}
Hope this helps and clarifies.

Related

Unable to connect the API connection to the logic App via ARM template in terraform

In my terraform I have created a logic app and its workflow with the help of a ARM Template. The 2 connections used in the logic app is also created via ARM template. But somehow even though the resources get created in AZURE. But when I got to the logic app, I always have to manually update the connection in the workflow. How can we make it automatic.
//First connection
resource "azurerm_template_deployment" "exampleeventhub" {
name = "acctesttemplate-44"
resource_group_name = Resourcegrpname
template_body = <<DEPLOY
{
"$schema": https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#,
"contentVersion": "1.0.0.0",
"parameters": {
"connections_eventhubs_name": {
"defaultValue": "eventhubs",
"type": "String"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Web/connections",
"apiVersion": "2016-06-01",
"name": "[parameters('connections_eventhubs_name')]",
"location": "qwerty",
"kind": "V1",
"properties": {
"displayName": "eventhubconnection",
"statuses": [
{
"status": "Connected"
}
],
"customParameterValues": {},
"nonSecretParameterValues": {},
"createdTime": "aaaaa",
"changedTime": "bbbb",
"api": {
"name": "[parameters('connections_eventhubs_name')]",
"displayName": "Event Hubs",
"description": "Connect to Azure Event Hubs to send and receive events.",
"iconUri": "[concat('https://connectoricons-prod.azureedge.net/releases/v1.0.1480/1.0.1480.2454/', parameters('connections_eventhubs_name'), '/icon.png')]",
"brandColor": "#c4d5ff",
"id": "[concat('/subscriptions/1111/providers/Microsoft.Web/locations/qwerty/managedApis/', parameters('connections_eventhubs_name'))]",
"type": "Microsoft.Web/locations/managedApis"
},
"testLinks": []
}
}
]
}
DEPLOY
deployment_mode = "Incremental"
}
//Second connection
resource "azurerm_template_deployment" "exampledatacollector" {
name = "acctesttemplate-45"
resource_group_name = Resourcegrpname
template_body = <<DEPLOY
{
"$schema": https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#,
"contentVersion": "1.0.0.0",
"parameters": {
"connections_thengadatacollector_name": {
"defaultValue": "thengadatacollector",
"type": "String"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Web/connections",
"apiVersion": "2016-06-01",
"name": "[parameters('connections_thengadatacollector_name')]",
"location": "qwerty",
"kind": "V1",
"properties": {
"displayName": "azuredatacollector",
"statuses": [
{
"status": "Connected"
}
],
"customParameterValues": {},
"nonSecretParameterValues": {
"username": "764a2b1e-431d-4e90-87b1-ea6a34dac48f"
},
"createdTime": "aaaa",
"changedTime": "bbbb",
"api": {
"name": "[parameters('connections_thengadatacollector_name')]",
"displayName": "Azure Log Analytics Data Collector",
"description": "Azure Log Analytics Data Collector will send data to any Azure Log Analytics workspace.",
"iconUri": "[concat('https://connectoricons-prod.azureedge.net/releases/v1.0.1480/1.0.1480.2454/', parameters('connections_thengadatacollector_name'), '/icon.png')]",
"brandColor": "#0072C6",
"id": "[concat('/subscriptions/1111/providers/Microsoft.Web/locations/qwerty/managedApis/', parameters('connections_thengadatacollector_name'))]",
"type": "Microsoft.Web/locations/managedApis"
},
"testLinks": []
}
}
]
}
DEPLOY
deployment_mode = "Incremental"
}
//Logic App
resource "azurerm_template_deployment" "example" {
name = "acctesttemplate-46"
resource_group_name = Resourcegrpname
template_body = <<DEPLOY
{
"$schema": https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#,
"contentVersion": "1.0.0.0",
"parameters": {
"workflows_logicapp_name": {
"defaultValue": "logicapp",
"type": "String"
},
"connections_thengadatacollector_externalid": {
"defaultValue": "/subscriptions/1111/resourceGroups/Resourcegrpname/providers/Microsoft.Web/connections/azureloganalyticsdatacollector",
"type": "String"
},
"connections_eventhubs_externalid": {
"defaultValue": "/subscriptions/1111/resourceGroups/Resourcegrpname/providers/Microsoft.Web/connections/eventhubs",
"type": "String"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Logic/workflows",
"apiVersion": "2017-07-01",
"name": "[parameters('workflows_logicapp_name')]",
"location": "qwerty",
"properties": {
"state": "Enabled",
"definition": {
"$schema": https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#,
"contentVersion": "1.0.0.0",
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"When_events_are_available_in_Event_Hub": {
"recurrence": {
"frequency": "Minute",
"interval": 3
},
"splitOn": "#triggerBody()",
"type": "ApiConnection",
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['eventhubs']['connectionId']"
}
},
"method": "get",
"path": "/#{encodeURIComponent('thengaeventhub')}/events/batch/head",
"queries": {
"contentType": "application/octet-stream",
"maximumEventsCount": 50
}
}
}
},
"actions": {
"Send_Data_2": {
"runAfter": {},
"type": "ApiConnection",
"inputs": {
"body": "#base64ToString(triggerBody()?['ContentData'])",
"headers": {
"Log-Type": "testcustimlog"
},
"host": {
"connection": {
"name": "#parameters('$connections')['thengadatacollector_1']['connectionId']"
}
},
"method": "post",
"path": "/api/logs"
}
}
}
},
"parameters": {
"$connections": {
"value": {
"thengadatacollector_1": {
"connectionId": "[parameters('connections_thengadatacollector_externalid')]",
"connectionName": "thengadatacollector",
"id": "/subscriptions/1111/providers/Microsoft.Web/locations/qwerty/managedApis/thengadatacollector"
},
"eventhubs": {
"connectionId": "[parameters('connections_eventhubs_externalid')]",
"connectionName": "eventhubs",
"id": "/subscriptions/1111/providers/Microsoft.Web/locations/qwerty/managedApis/eventhubs"
}
}
}
}
}
}
]
}
DEPLOY
deployment_mode = "Incremental"
}
It is an expected behaviour , if you deploy the ARM Template, your both API Connections will have been created but inside logic apps you will have to update manually the connection by entering your credentials for the service. This is because for finalizing the API connection you need to give the consent but which is not possible in ARM template.
But if you need to finalize the API Connection creation without opening every Logic Apps then you can use PowerShell script .This script will retrieve a consent link for a connection for an OAuth Logic Apps connector. It will then open the consent link and complete authorization to enable a connection.
Param(
[string] $ResourceGroupName = 'YourRG',
[string] $ResourceLocation = 'eastus | westus | etc.',
[string] $api = 'office365 | dropbox | dynamicscrmonline | etc.',
[string] $ConnectionName = 'YourConnectionName',
[string] $subscriptionId = '80d4fe69-xxxx-xxxx-a938-9250f1c8ab03',
[bool] $createConnection = $true
)
#region mini window, made by Scripting Guy Blog
Function Show-OAuthWindow {
Add-Type -AssemblyName System.Windows.Forms
$form = New-Object -TypeName System.Windows.Forms.Form -Property #{Width=600;Height=800}
$web = New-Object -TypeName System.Windows.Forms.WebBrowser -Property #{Width=580;Height=780;Url=($url -f ($Scope -join "%20")) }
$DocComp = {
$Global:uri = $web.Url.AbsoluteUri
if ($Global:Uri -match "error=[^&]*|code=[^&]*") {$form.Close() }
}
$web.ScriptErrorsSuppressed = $true
$web.Add_DocumentCompleted($DocComp)
$form.Controls.Add($web)
$form.Add_Shown({$form.Activate()})
$form.ShowDialog() | Out-Null
}
#endregion
#login to get an access code
Login-AzureRmAccount
#select the subscription
$subscription = Select-AzureRmSubscription -SubscriptionId $subscriptionId
#if the connection wasn't alrady created via a deployment
if($createConnection)
{
$connection = New-AzureRmResource -Properties #{"api" = #{"id" = "subscriptions/" + $subscriptionId + "/providers/Microsoft.Web/locations/" + $ResourceLocation + "/managedApis/" + $api}; "displayName" = $ConnectionName; } -ResourceName $ConnectionName -ResourceType "Microsoft.Web/connections" -ResourceGroupName $ResourceGroupName -Location $ResourceLocation -Force
}
#else (meaning the conneciton was created via a deployment) - get the connection
else{
$connection = Get-AzureRmResource -ResourceType "Microsoft.Web/connections" -ResourceGroupName $ResourceGroupName -ResourceName $ConnectionName
}
Write-Host "connection status: " $connection.Properties.Statuses[0]
$parameters = #{
"parameters" = ,#{
"parameterName"= "token";
"redirectUrl"= "https://ema1.exp.azure.com/ema/default/authredirect"
}
}
#get the links needed for consent
$consentResponse = Invoke-AzureRmResourceAction -Action "listConsentLinks" -ResourceId $connection.ResourceId -Parameters $parameters -Force
$url = $consentResponse.Value.Link
#prompt user to login and grab the code after auth
Show-OAuthWindow -URL $url
$regex = '(code=)(.*)$'
$code = ($uri | Select-string -pattern $regex).Matches[0].Groups[2].Value
Write-output "Received an accessCode: $code"
if (-Not [string]::IsNullOrEmpty($code)) {
$parameters = #{ }
$parameters.Add("code", $code)
# NOTE: errors ignored as this appears to error due to a null response
#confirm the consent code
Invoke-AzureRmResourceAction -Action "confirmConsentCode" -ResourceId $connection.ResourceId -Parameters $parameters -Force -ErrorAction Ignore
}
#retrieve the connection
$connection = Get-AzureRmResource -ResourceType "Microsoft.Web/connections" -ResourceGroupName $ResourceGroupName -ResourceName $ConnectionName
Write-Host "connection status now: " $connection.Properties.Statuses[0]
Reference:
Deploy Logic Apps & API Connection with ARM · in my room (bruttin.com)

Azure Functions consumption plan naming

I've created a new Function App in Azure. I picked a consumption plan for the App Service Plan.
Once the app is created I now have a new App Service Plan called "WestEuropePlan" In my resource group.
Next thing. IT department says "WestEuropePlan" is not the correct naming convention for App Service Plans.
What are my options. When creating the Function App Im not allowed to pick or name an existing plan when using consumption based plans.
I cannot rename my autogenerated plan.
I cannot manually create a consumption based plan previous to creating the Function App.
What do i do? Is my only option to not use Consumption based plans and instead create a normal app service plan that I can name myself?
Is there something I can do from azure CLI or using ARM templates?
Above answers will help if you are doing using Azure CLI, if you want to do via Portal itself, you can do as follows,
On the Azure function Review + create step, there is an option to Download the template for automation and you can click on it. Then the Template will be displayed for downloading.
Now click on Deploy
Now you can easily change the Hosting Plan Name, agree to T&Cs and click on Purchase.
More Information: http://jaliyaudagedara.blogspot.com/2020/08/azure-functions-consumption-plan-custom.html
You can create a Azure Function on Consumption plan with your choice of name for consumption plan using ARM Template. Below is the sample template and parameter file:
Templatefile.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"appName": {
"type": "string",
"metadata": {
"description": "The name of the function app that you wish to create."
}
},
"storageAccountType": {
"type": "string",
"defaultValue": "Standard_LRS",
"allowedValues": ["Standard_LRS", "Standard_GRS", "Standard_RAGRS"],
"metadata": {
"description": "Storage Account type"
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for all resources."
}
},
"runtime": {
"type": "string",
"defaultValue": "node",
"allowedValues": ["node", "dotnet", "java"],
"metadata": {
"description": "The language worker runtime to load in the function app."
}
}
},
"variables": {
"functionAppName": "[parameters('appName')]",
"hostingPlanName": "[parameters('appName')]",
"applicationInsightsName": "[parameters('appName')]",
"storageAccountName": "[concat(uniquestring(resourceGroup().id), 'azfunctions')]",
"storageAccountid": "[concat(resourceGroup().id,'/providers/','Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]",
"functionWorkerRuntime": "[parameters('runtime')]"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"name": "[variables('storageAccountName')]",
"apiVersion": "2016-12-01",
"location": "[parameters('location')]",
"kind": "Storage",
"sku": {
"name": "[parameters('storageAccountType')]"
}
},
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2015-04-01",
"name": "[variables('hostingPlanName')]",
"location": "[parameters('location')]",
"properties": {
"name": "[variables('hostingPlanName')]",
"computeMode": "Dynamic",
"sku": "Dynamic"
}
},
{
"apiVersion": "2015-08-01",
"type": "Microsoft.Web/sites",
"name": "[variables('functionAppName')]",
"location": "[parameters('location')]",
"kind": "functionapp",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
],
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"siteConfig": {
"appSettings": [
{
"name": "AzureWebJobsDashboard",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]"
},
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]"
},
{
"name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]"
},
{
"name": "WEBSITE_CONTENTSHARE",
"value": "[toLower(variables('functionAppName'))]"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~2"
},
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"value": "8.11.1"
},
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(resourceId('microsoft.insights/components/', variables('applicationInsightsName')), '2015-05-01').InstrumentationKey]"
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "[variables('functionWorkerRuntime')]"
}
]
}
}
},
{
"apiVersion": "2018-05-01-preview",
"name": "[variables('applicationInsightsName')]",
"type": "microsoft.insights/components",
"location": "East US",
"tags": {
"[concat('hidden-link:', resourceGroup().id, '/providers/Microsoft.Web/sites/', variables('applicationInsightsName'))]": "Resource"
},
"properties": {
"ApplicationId": "[variables('applicationInsightsName')]",
"Request_Source": "IbizaWebAppExtensionCreate"
}
}
]
}
Reference: https://github.com/Azure/azure-quickstart-templates/tree/master/101-function-app-create-dynamic
You can create from this ARM Template. No app insights and it'll ask appName, hostingPlanName, storageAccountName, storageAccountType, location and runtime
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"appName": {
"type": "string",
"metadata": {
"description": "The name of the function app that you wish to create."
}
},
"hostingPlanName": {
"type": "string",
"metadata": {
"description": "The name of the consumption plan that you wish to create."
}
},
"storageAccountName": {
"type": "string",
"metadata": {
"description": "The name of the storage account name that you wish to create."
}
},
"storageAccountType": {
"type": "string",
"defaultValue": "Standard_LRS",
"allowedValues": [
"Standard_LRS",
"Standard_GRS",
"Standard_RAGRS"
],
"metadata": {
"description": "Storage Account type"
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for all resources."
}
},
"runtime": {
"type": "string",
"defaultValue": "node",
"allowedValues": [
"node",
"dotnet",
"java"
],
"metadata": {
"description": "The language worker runtime to load in the function app."
}
}
},
"variables": {
"functionAppName": "[parameters('appName')]",
"hostingPlanName": "[parameters('hostingPlanName')]",
"storageAccountName": "[parameters('storageAccountName')]",
"storageAccountid": "[concat(resourceGroup().id,'/providers/','Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]",
"functionWorkerRuntime": "[parameters('runtime')]"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"name": "[variables('storageAccountName')]",
"apiVersion": "2016-12-01",
"location": "[parameters('location')]",
"kind": "Storage",
"sku": {
"name": "[parameters('storageAccountType')]"
}
},
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2018-02-01",
"name": "[variables('hostingPlanName')]",
"location": "[parameters('location')]",
"sku": {
"name": "Y1",
"tier": "Dynamic"
},
"properties": {
"name": "[variables('hostingPlanName')]",
"computeMode": "Dynamic"
}
},
{
"apiVersion": "2015-08-01",
"type": "Microsoft.Web/sites",
"name": "[variables('functionAppName')]",
"location": "[parameters('location')]",
"kind": "functionapp",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
],
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"siteConfig": {
"appSettings": [
{
"name": "AzureWebJobsDashboard",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]"
},
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]"
},
{
"name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]"
},
{
"name": "WEBSITE_CONTENTSHARE",
"value": "[toLower(variables('functionAppName'))]"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~2"
},
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"value": "8.11.1"
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "[variables('functionWorkerRuntime')]"
}
]
}
}
}
]
}
I recommend you to use Az PowerShell or AzureCLI to perform the naming of your Function App Consumption Plan, it's easier to maintain than ARM Template.
The trick is that you need to create a B1 plan first (so with your custom name) then change some settings on your FunctionApp to fit the ConsumptionPlan restriction (i.e.: AlwaysOn=$false), then you can update/change your App Service Plan B1 to a Consumption Plan (called Y1)
Please find my script in PowerShell to create a Linux Consumption Plan :
(For Windows plan, you can remove "kind" and "properties.reserved=true" in the variable $fullObject, replace "linux" by "windows" on the variable $os_type and remove $my_runtimeVersion variable and change $my_runtime variable from "python" to "dotnet" (or remove it as by default it's dotnet))
# Function App configuration object - Need to be a Basic Tier first as you cannot directly create a consumption plan
$fullObject = #{
location = "West Europe"
sku = #{
name = "B1"
tier = "Basic"
}
kind = "linux"
properties = #{
reserved = $true
}
}
$resourceGroupName = "rg-my-test"
$serverFarmName = "aspl-my-test"
$storageName = "stg-my-test"
$functionAppName = "fa-my-test"
$my_runtime = "python"
$my_runtimeVersion = "3.8"
$os_type = "linux"
Write-Host "Step 1: CREATING APP SERVICE PLAN B1:Basic named [$serverFarmName]"
# Create a server farm which will host the function app in the resource group specified
New-AzResource -ResourceGroupName $resourceGroupName -ResourceType "Microsoft.Web/serverfarms" -Name $serverFarmName -IsFullObject -PropertyObject $fullObject -Force
Write-Host "Step 1: Done"
Write-Host "Step 2: CREATING STORAGE ACCOUNT named [$storageName]"
# Create a storage account which will contain the Azure Function script
New-AzStorageAccount -ResourceGroupName $resourceGroupName -AccountName $storageName -Location westeurope -SkuName Standard_LRS
Write-Host "Step 2: Done"
Write-Host "Step 3: CREATING FUNCTION APP named [$functionAppName]"
# Create a function app in the server farm previously created
New-AzFunctionApp -ResourceGroupName $resourceGroupName -Name $functionAppName -PlanName $serverFarmName -StorageAccount $storageName -Runtime $my_runtime -FunctionsVersion 3 -OSType $os_type -RuntimeVersion $my_runtimeVersion -DisableApplicationInsights
Write-Host "Step 3: Done"
Write-Host "Step 4a: GET FUNCTION APP as an PSObject"
$funcApp = Get-AzResource -ResourceType 'microsoft.web/sites' -ResourceGroupName $resourceGroupName -ResourceName $functionAppName
Write-Host "Step 4a: Done"
Write-Host "Step 4b: SET FUNCTION APP settings"
Write-Host " siteConfig:"
Write-Host " AlwaysOn: false"
Write-Host " FtpsState: Disabled"
Write-Host " MinTlsVersion: 1.2"
Write-Host " Http20Enabled: true"
Write-Host " HttpsOnly: true"
$fullObject = #{
siteConfig = #{
AlwaysOn = $false
FtpsState = "Disabled"
MinTlsVersion = "1.2"
Http20Enabled = $true
}
HttpsOnly = $true
}
$funcApp | Set-AzResource -PropertyObject $fullObject -Force
Write-Host "Step 4b: Done"
Write-Host "Step 5: Set App Service Plan to Dynamic Consumption Plan"
Set-AzAppServicePlan -Name $serverFarmName -ResourceGroupName $resourceGroupName -Tier Y1
Write-Host "Step 5: Done"
In Azure CLI, the command to switch the plan to Consumption Plan is:
az appservice plan update --name aspl-my-test --resource-group rg-my-test --set sku.name=Y1

Configure SSL on Azure Web App using ARM. The parameter {0} has an invalid value. ExtendedCode 51008,

I am trying to configure SSL and custom domain name using this ARM Template.
Full error message:
New-AzureRmResourceGroupDeployment : 4:03:36 AM - Resource Microsoft.Web/certificates '<certificateName>' failed with message '{
"Code": "BadRequest",
"Message": "The parameter httpResponseMessage has an invalid value.",
"Target": null,
"Details": [
{
"Message": "The parameter httpResponseMessage has an invalid value."
},
{
"Code": "BadRequest"
},
{
"ErrorEntity": {
"ExtendedCode": "51008",
"MessageTemplate": "The parameter {0} has an invalid value.",
"Parameters": [
"httpResponseMessage"
],
"Code": "BadRequest",
"Message": "The parameter httpResponseMessage has an invalid value."
}
}
],
"Innererror": null
}'
The error message hints to Microsoft.Web/certificates in the ARM template
{
"type":"Microsoft.Web/certificates",
"name":"[parameters('certificateName')]",
"apiVersion":"2016-03-01",
"location":"[parameters('existingAppLocation')]",
"properties":{
"keyVaultId":"[parameters('existingKeyVaultId')]",
"keyVaultSecretName":"[parameters('existingKeyVaultSecretName')]",
"serverFarmId":"[parameters('existingServerFarmId')]"
}
},
The values of those parameters are:
certificateName: 16charstring
existingKeyVaultId: /subscriptions/<subscriptionid>/resourceGroups/<ressourcegroupname>/providers/Microsoft.KeyVault/vaults/<VaultName>
existingKeyVaultSecretName: https://<VaultName>.vault.azure.net:443/secrets/<certificateName>/12345678901234567890
existingServerFarmId: /subscriptions/<subscriptionid>/resourceGroups/<ressourcegroupname>/providers/Microsoft.Web/serverFarms/<AppServicePlanName>
I am using the Invoke-AddCertToKeyVault cmdlet found in RPHelper library to add the certicate to the vault
Write-Host "Reading pfx file from $ExistingPfxFilePath"
$cert = new-object System.Security.Cryptography.X509Certificates.X509Certificate2 $ExistingPfxFilePath, $Password
$bytes = [System.IO.File]::ReadAllBytes($ExistingPfxFilePath)
$base64 = [System.Convert]::ToBase64String($bytes)
$jsonBlob = #{
data = $base64
dataType = 'pfx'
password = $Password
} | ConvertTo-Json
$contentbytes = [System.Text.Encoding]::UTF8.GetBytes($jsonBlob)
$content = [System.Convert]::ToBase64String($contentbytes)
$secretValue = ConvertTo-SecureString -String $content -AsPlainText -Force
Write-Host "Writing secret to $CertificateName in vault $VaultName. Secret value " $secretValue
$secret = Set-AzureKeyVaultSecret -VaultName $VaultName -Name $CertificateName -SecretValue $secretValue
$output = #{};
$output.SourceVault = $resourceId;
$output.CertificateURL = $secret.Id;
$output.CertificateThumbprint = $cert.Thumbprint;
Can you tell me what is wrong?
According to your description, I guess there are something wrong with your template certificate parameters.
Since the link you have posted couldn't be accessed. I write a test arm template and it works well.
I suggest you could follow below template to create the web app.
Notice:
I used powershell to enable the 'Microsoft.Web' Resource Provider directly access the azure key Vault.
Login-AzureRmAccount
Set-AzureRmContext -SubscriptionId AZURE_SUBSCRIPTION_ID
Set-AzureRmKeyVaultAccessPolicy -VaultName KEY_VAULT_NAME -ServicePrincipalName abfa0a7c-a6b6-4736-8310-5855508787cd -PermissionsToSecrets get
The result:
Then you could use below powershell command to insert the certificate to the KeyVault.
$pfxFilePath = "PFX_CERTIFICATE_FILE_PATH" # Change this path
$pwd = "PFX_CERTIFICATE_PASSWORD" # Change this password
$flag = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable
$collection = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection
$collection.Import($pfxFilePath, $pwd, $flag)
$pkcs12ContentType = [System.Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12
$clearBytes = $collection.Export($pkcs12ContentType)
$fileContentEncoded = [System.Convert]::ToBase64String($clearBytes)
$secret = ConvertTo-SecureString -String $fileContentEncoded -AsPlainText –Force
$secretContentType = 'application/x-pkcs12'
Set-AzureKeyVaultSecret -VaultName KEY_VAULT_NAME -Name KEY_VAULT_SECRET_NAME -SecretValue $Secret -ContentType $secretContentType # Change Key Vault name and Secret name
After this operation, you could just use the KeyVaultSecretName to directly access the KeyVault to get the value.
The total template:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
"contentVersion": "1.0.0.0",
"parameters": {
"webAppName": {
"type": "string",
"metadata": {
"description": "The name of the web app that you wish to create."
}
},
"customHostname": {
"type": "string",
"metadata": {
"description": "The custom hostname that you wish to add."
}
},
"existingKeyVaultId": {
"type": "string",
"metadata": {
"description": "Existing Key Vault resource Id with an access policy to allow Microsoft.Web RP to read Key Vault secrets (Checkout README.md for more information)"
}
},
"existingKeyVaultSecretName": {
"type": "string",
"metadata": {
"description": "Key Vault Secret that contains a PFX certificate"
}
}
},
"variables": {
"appServicePlanName": "[concat(parameters('webAppName'),'-asp-', uniquestring(resourceGroup().id))]",
"certificateName": "[concat(parameters('webAppName'),'-cert-', uniquestring(resourceGroup().id))]"
},
"resources": [
{
"apiVersion": "2016-03-01",
"name": "[variables('appServicePlanName')]",
"type": "Microsoft.Web/serverfarms",
"location": "[resourceGroup().location]",
"properties": {
"name": "[variables('appServicePlanName')]"
},
"sku": {
"name": "P1",
"tier": "Premium",
"size": "1",
"family": "P",
"capacity": "1"
}
},
{
"apiVersion": "2016-03-01",
"name": "[parameters('webAppName')]",
"type": "Microsoft.Web/sites",
"location": "[resourceGroup().location]",
"properties": {
"name": "[parameters('webAppName')]",
"serverFarmId": "[resourceId('Microsoft.Web/serverFarms',variables('appServicePlanName'))]"
},
"dependsOn": [
"[concat('Microsoft.Web/serverFarms/',variables('appServicePlanName'))]"
]
},
{
"type": "Microsoft.Web/certificates",
"name": "[variables('certificateName')]",
"apiVersion": "2016-03-01",
"location": "[resourceGroup().location]",
"properties": {
"keyVaultId": "[parameters('existingKeyVaultId')]",
"keyVaultSecretName": "[parameters('existingKeyVaultSecretName')]",
"serverFarmId": "[resourceId('Microsoft.Web/serverFarms',variables('appServicePlanName'))]"
},
"dependsOn": [
"[concat('Microsoft.Web/sites/',parameters('webAppName'))]"
]
},
{
"type": "Microsoft.Web/sites/hostnameBindings",
"name": "[concat(parameters('webAppName'), '/', parameters('customHostname'))]",
"apiVersion": "2016-03-01",
"location": "[resourceGroup().location]",
"properties": {
"sslState": "SniEnabled",
"thumbprint": "[reference(resourceId('Microsoft.Web/certificates', variables('certificateName'))).Thumbprint]"
},
"dependsOn": [
"[concat('Microsoft.Web/certificates/',variables('certificateName'))]"
]
}
]
}
The WebSite.parameters:
{
"$schema": "https://schema.management.azure.com/schemas/2015-08-01/deploymentParameters.json",
"contentVersion": "1.0.0.0",
"parameters": {
"webAppName": {
"value": "yourwebappname"
},
"customHostname": {
"value": "yourcustomdomianname"
},
"existingKeyVaultId": {
"value": "/subscriptions/subscriptionsID/resourceGroups/resourceGroupsName/providers/Microsoft.KeyVault/vaults/vaultsName"
},
"existingKeyVaultSecretName": {
"value": "The key vaults SecretName"
}
}
}
Result:

Create Table in Azure Storage Account

Is there's a way to create a Table inside Azure Storage Account using ARM template? I can achieve that using PowerShell but can't find a way to do it using JSON template, also when I browse my deployment resources using (https://resources.azure.com) I can't see any reference to the created table under the storage account, any idea why?
Thanks,
A Seyam
You can create an Azure Storage account with a table via ARM like this, using a tableServices/tables sub-resource on your storageAccount resource:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"storageAccountName": {
"type": "string",
"minLength": 3,
"maxLength": 24
},
"storageAccountSku": {
"type": "string",
"defaultValue": "Standard_LRS",
"allowedValues": [
"Standard_LRS",
"Standard_GRS",
"Standard_RAGRS"
]
},
"tableName": {
"type": "string",
"minLength": 3,
"maxLength": 63
}
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"name": "[parameters('storageAccountName')]",
"apiVersion": "2019-06-01",
"location": "[resourceGroup().location]",
"kind": "StorageV2",
"sku": {
"name": "[parameters('storageAccountSku')]"
},
"resources": [
{
"name": "[concat('default/', parameters('tableName'))]",
"type": "tableServices/tables",
"apiVersion": "2019-06-01",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]"
]
}
]
}
]
}
The functionality is documented on the ARM Template spec page for tableServices/tables.
As far as I know, no. You could look at Get started with Azure Table storage using .NET/PHP/Python/... for details.
The Table service exposes Account, Tables, Entity via the REST API, so you couldn't see them in the portal. You can check out Addressing Table Service Resources for more info.
Creating Azure storage using ARM template with some easy steps. Please find the following steps to implement it.
Step 1: Open your powershell and login your account with Connect-AzureRmAccount
step 2: add your SubscriptionId Select-AzureRmSubscription -SubscriptionId <your SubscriptionId>
step 3: Create Resource Group New-AzureRmResourceGroup -Name yourResourceGroup -Location "South Central US"
Step 4: create azuredeploy.json and azuredeploy.parameters.json
azuredeploy.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"storageAccountName": {
"type": "string",
"metadata": {
"description": "The name of the Azure Storage account."
}
},
"containerName": {
"type": "string",
"defaultValue": "logs",
"metadata": {
"description": "The name of the blob container."
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "The location in which the Azure Storage resources should be deployed."
}
}
},
"resources": [
{
"name": "[parameters('storageAccountName')]",
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2018-02-01",
"location": "[parameters('location')]",
"kind": "StorageV2",
"sku": {
"name": "Standard_LRS",
"tier": "Standard"
},
"properties": {
"accessTier": "Hot"
},
"resources": [
{
"name": "[concat('default/', parameters('containerName'))]",
"type": "blobServices/containers",
"apiVersion": "2018-03-01-preview",
"dependsOn": [
"[parameters('storageAccountName')]"
]
}
]
}
]
}
azuredeploy.parameters.json
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"storageAccountName": {
"value": "yourstorage"
}
}
}
Step 5: run the following command
New-AzureRmResourceGroupDeployment -Name myDeployment -ResourceGroupName yourResourceGroup -TemplateFile <location>\azuredeploy.json -TemplateParameterFile <location>\azuredeploy.parameters.json
Step 6:
$saContext = (Get-AzureRmStorageAccount -ResourceGroupName yourResourceGroup -Name sitastoragee).Context
New-AzureStorageTable –Name yourtablestorage –Context $saContext

Create VM from existing VHD: Preview portal

Does anyone now how to create a VM from an existing VHD in the new azure portal ?
I can find lots of info on how to do this in manage.windowsazure.com, but nothing on this functionality in portal.azure.com.
It can't be done literally in the portal. You will have to use powershell.
Create a storageaccount. For example in the portal.
Upload the VHD to azure. To do this, run the following line in powershell after logging in with Login-AzureRmAccount (change the parameters between <> and the path to the vhd on your harddisk):
Add-AzurermVhd -Destination "https://<StorageAccountName>.blob.core.windows.net/<containerName>/<vhdname>.vhd" -LocalFilePath "D:\Virtual Machines\myharddisk.vhd" -ResourceGroupName "<ResourceGroupName" -Overwrite
Create an ARM template.
Multiple possiblities what you can do.
For example choose a template from the Azure Quickstart templates, for example 101
What I have done is:
Created a new project in Visual Studio 2015.
Choose the following project: Cloud->Azure Resource Group
Choose the following template: Windows Virtual Machine
Changed some parameters and removed all stuff that is not necessary.
What it does now is: Create a Windows Virtual Machine using the uploaded vhd as harddisk.
It's using a parameters json file now, and also some variables have to be set in the WindowsVirtualMachine.json
This could be refactored ofcourse. but for now it will do what's needed.
For this sample you have to have the following directory structure (just like Visual Studio creates it)
ProjectDirectory/Scripts/Deploy-AzureResourceGroup.ps1
ProjectDirectory/Templates/WindowsVirtualMachine.json
ProjectDirectory/Templates/WindowsVirtualMachine.parameters.json
Deploy-AzureResourceGroup.ps1
#Requires -Version 3.0
#Requires -Module AzureRM.Resources
#Requires -Module Azure.Storage
Param(
[string] [Parameter(Mandatory=$true)] $ResourceGroupLocation,
[string] $ResourceGroupName = 'CreateImage',
[string] $TemplateFile = '..\Templates\WindowsVirtualMachine.json',
[string] $TemplateParametersFile = '..\Templates\WindowsVirtualMachine.parameters.json'
)
Import-Module Azure -ErrorAction SilentlyContinue
try {
[Microsoft.Azure.Common.Authentication.AzureSession]::ClientFactory.AddUserAgent("VSAzureTools-$UI$($host.name)".replace(" ","_"), "2.8")
} catch { }
Set-StrictMode -Version 3
$OptionalParameters = New-Object -TypeName Hashtable
$TemplateFile = [System.IO.Path]::Combine($PSScriptRoot, $TemplateFile)
$TemplateParametersFile = [System.IO.Path]::Combine($PSScriptRoot, $TemplateParametersFile)
# Create or update the resource group using the specified template file and template parameters file
New-AzureRmResourceGroup -Name $ResourceGroupName -Location $ResourceGroupLocation -Verbose -Force -ErrorAction Stop
New-AzureRmResourceGroupDeployment -Name ((Get-ChildItem $TemplateFile).BaseName + '-' + ((Get-Date).ToUniversalTime()).ToString('MMdd-HHmm')) `
-ResourceGroupName $ResourceGroupName `
-TemplateFile $TemplateFile `
-TemplateParameterFile $TemplateParametersFile `
#OptionalParameters `
-Force -Verbose
WindowsVirtualMachine.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"dnsNameForPublicIP": {
"type": "string",
"minLength": 1,
"metadata": {
"description": "Globally unique DNS Name for the Public IP used to access the Virtual Machine."
}
}
},
"variables": {
"OSDiskName": "<vhdNameWithoutExtension>",
"vhdStorageContainerName": "<containerName>",
"storageAccountName": "<StorageAccountName>",
"nicName": "myVMNic",
"addressPrefix": "10.0.0.0/16",
"subnetName": "Subnet",
"subnetPrefix": "10.0.0.0/24",
"vhdStorageType": "Standard_LRS",
"publicIPAddressName": "myPublicIP",
"publicIPAddressType": "Dynamic",
"vhdStorageName": "[concat('vhdstorage', uniqueString(resourceGroup().id))]",
"vmName": "MyWindowsVM",
"vmSize": "Standard_A2",
"virtualNetworkName": "MyVNET",
"vnetId": "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]",
"subnetRef": "[concat(variables('vnetId'), '/subnets/', variables('subnetName'))]"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"name": "[variables('vhdStorageName')]",
"apiVersion": "2015-06-15",
"location": "[resourceGroup().location]",
"tags": {
"displayName": "StorageAccount"
},
"properties": {
"accountType": "[variables('vhdStorageType')]"
}
},
{
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/publicIPAddresses",
"name": "[variables('publicIPAddressName')]",
"location": "[resourceGroup().location]",
"tags": {
"displayName": "PublicIPAddress"
},
"properties": {
"publicIPAllocationMethod": "[variables('publicIPAddressType')]",
"dnsSettings": {
"domainNameLabel": "[parameters('dnsNameForPublicIP')]"
}
}
},
{
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/virtualNetworks",
"name": "[variables('virtualNetworkName')]",
"location": "[resourceGroup().location]",
"tags": {
"displayName": "VirtualNetwork"
},
"properties": {
"addressSpace": {
"addressPrefixes": [
"[variables('addressPrefix')]"
]
},
"subnets": [
{
"name": "[variables('subnetName')]",
"properties": {
"addressPrefix": "[variables('subnetPrefix')]"
}
}
]
}
},
{
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/networkInterfaces",
"name": "[variables('nicName')]",
"location": "[resourceGroup().location]",
"tags": {
"displayName": "NetworkInterface"
},
"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-06-15",
"type": "Microsoft.Compute/virtualMachines",
"name": "[variables('vmName')]",
"location": "[resourceGroup().location]",
"tags": {
"displayName": "VirtualMachine"
},
"dependsOn": [
"[concat('Microsoft.Storage/storageAccounts/', variables('vhdStorageName'))]",
"[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]"
],
"properties": {
"hardwareProfile": {
"vmSize": "[variables('vmSize')]"
},
"storageProfile": {
"osDisk": {
"name": "osdisk",
"osType": "Windows",
"vhd": {
"uri": "[concat('http://', variables('storageAccountName'), '.blob.core.windows.net/', variables('vhdStorageContainerName'), '/', variables('OSDiskName'), '.vhd')]"
},
"caching": "ReadWrite",
"createOption": "Attach"
}
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
}
]
}
}
}
]
}
WindowsVirtualMachine.parameters.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"dnsNameForPublicIP": {
"value": "<someUniqueNameForYourDnsName>"
}
}
}
Execute the powershell script
Open up a Powershell command and execute the ps1 script. You only have to pass the location where you want the vm to be created like: (you should already be logged in with Login-AzureRmAccount)
Before running change the parameters in both json files!
.\Deploy-AzureResourceGroup.ps1 "West Europe"
The logging should tell you that the VM is created successfully.
Today (Oct 2016) it still can´t be done in the new portal.
But for completeness: You can do it in the old portal (https://manage.windowsazure.com):
Click New - Compute - Virtual Machine - From Gallery.
On the left either select MY IMAGES or MY DISKS and select the VHD you want to use.
Follow the instructions as usual.

Resources