Enable Azure StorageV2 static website (preview) feature using ARM template - azure

Im trying to write an ARM template that creates a storage account with the new static website (preview) feature:
When I go to the Automation Script blade I don't see any related settings within the ARM template:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"storageAccounts_spastore_name": {
"defaultValue": "spastore",
"type": "String"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"sku": {
"name": "Standard_LRS",
"tier": "Standard"
},
"kind": "StorageV2",
"name": "[parameters('storageAccounts_spastore_name')]",
"apiVersion": "2018-02-01",
"location": "westeurope",
"tags": {
"purpose": "example"
},
"scale": null,
"properties": {
"networkAcls": {
"bypass": "AzureServices",
"virtualNetworkRules": [],
"ipRules": [],
"defaultAction": "Allow"
},
"supportsHttpsTrafficOnly": false,
"encryption": {
"services": {
"file": {
"enabled": true
},
"blob": {
"enabled": true
}
},
"keySource": "Microsoft.Storage"
},
"accessTier": "Hot"
},
"dependsOn": []
}
]
}
I also don't see any related settings within the Azure Resource Explorer. I am aware that I have to use a newer API version as well but I don't know how to enable the feature using an ARM Template?

I don't think you can (at least as of today). ARM templates are meant for controlling the Control Plane whereas Static Websites Settings feature is exposed as part of Data Plane which is accessed by Storage Service REST API.
With the announcement of RBAC (and Azure AD roles) for Azure Storage, I am seeing some of the operations from Storage Service REST API becoming available in Storage Resource Provider API, so my guess is that sooner or later this functionality will be exposed there as well. Then you should be able to configure it through ARM templates.

It is ugly but you can do it with a deployment script in arm/bicep:
param deploymentScriptTimestamp string = utcNow()
param indexDocument string = 'index.html'
param errorDocument404Path string = 'error.html'
var storageAccountContributorRoleDefinitionId = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')
resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities#2018-11-30' = {
name: 'DeploymentScript'
location: location
}
resource roleAssignment 'Microsoft.Authorization/roleAssignments#2020-04-01-preview' = {
scope: storageAccount
name: guid(resourceGroup().id, storageAccountContributorRoleDefinitionId)
properties: {
roleDefinitionId: storageAccountContributorRoleDefinitionId
principalId: managedIdentity.properties.principalId
}
}
resource deploymentScript 'Microsoft.Resources/deploymentScripts#2020-10-01' = {
name: 'deploymentScript'
location: location
kind: 'AzurePowerShell'
identity: {
type: 'UserAssigned'
userAssignedIdentities: {
'${managedIdentity.id}': {}
}
}
dependsOn: [
roleAssignment
storageAccount
]
properties: {
azPowerShellVersion: '3.0'
scriptContent: '''
param(
[string] $ResourceGroupName,
[string] $StorageAccountName,
[string] $IndexDocument,
[string] $ErrorDocument404Path)
$ErrorActionPreference = 'Stop'
$storageAccount = Get-AzStorageAccount -ResourceGroupName $ResourceGroupName -AccountName $StorageAccountName
$ctx = $storageAccount.Context
Enable-AzStorageStaticWebsite -Context $ctx -IndexDocument $IndexDocument -ErrorDocument404Path $ErrorDocument404Path
'''
forceUpdateTag: deploymentScriptTimestamp
retentionInterval: 'PT4H'
arguments: '-ResourceGroupName ${resourceGroup().name} -StorageAccountName ${accountName} -IndexDocument ${indexDocument} -ErrorDocument404Path ${errorDocument404Path}'
}
}
see: azure example for static website, resource templates and scripts

Related

Get VirtualMachineScaleSet instanceview for a ResourceGroup

I am trying to get instanceview objects(VirtualMachineScaleSetInstanceViewInner) of all Azure's VirtualMachineScaleSets under a Subscription and this requires both ResourceGroup Name and Vmss name together.
azureResourceManager.virtualMachines().manager().serviceClient().getVirtualMachineScaleSets().getInstanceView(resourceGroupName, virtualMachineScaleSet.name(), Context.NONE);
How do I get specific VirtualMachineScaleSets under a ResourceGroup? I only see AzureResourceManager.ResourceGroups() and AzureResourceManager.virtualMachineScaleSets(), but nothing that gets virtualMachineScaleSets under a ResourceGroup.
Thanks
I have tried to get the VMSS instance in a Resource group by using the below RestApi:
GET https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}?api-version=2022-08-01
output:
Body:
{
"name": "rajtestVMSS",
"id": "/subscriptions/*********/resourceGroups/abcaaaa/providers/Microsoft.Compute/virtualMachineScaleSets/rajtestVMSS",
"type": "Microsoft.Compute/virtualMachineScaleSets",
"location": "westus2",
"tags": {
"azsecpack": "nonprod",
"platformsettings.host_environment.service.platform_optedin_for_rootcerts": "true"
},
"sku": {
"name": "Standard_D2s_v3",
"tier": "Standard",
"capacity": 2
},
"properties": {
"singlePlacementGroup": false,
"upgradePolicy": {
"mode": "Manual"
},
"scaleInPolicy": {
"rules": [
"Default"
]
},
"virtualMachineProfile": {
"osProfile": {
"computerNamePrefix": "rajtestvm",
"adminUsername": "rajtest",
"windowsConfiguration": {
"provisionVMAgent": true,
"enableAutomaticUpdates": true,
"enableVMAgentPlatformUpdates": false
------------------
------------------
------------------
You can use the below java code to get the VirtualMachine ScaleSet instanceview for a ResourceGroup.
import com.azure.core.util.Context;
public final class Main {
public static void getAVirtualMachineScaleSet(com.azure.resourcemanager.AzureResourceManager azure) {
azure
.virtualMachines()
.manager()
.serviceClient()
.getVirtualMachineScaleSets()
.getByResourceGroupWithResponse("myResourceGroup", "myVirtualMachineScaleSet", null, Context.NONE);
}
}
Thanks to #XiaofeiCao for the github link to know more about Azure Resource Manager client library for Java.

How to deploy App Service with managed SSL certificate using ARM

I want create an Azure App Service with a custom hostname binding and a managed SSL certificate.
When I create a single Bicep-template, the certificate resource can only be deployed if the hostname binding is already created. But to create a hostname binding, I need the certificate thumbprint.
Updating the hostname binding in the same template also is not possible, as a resource can only exist once in a template.
// hostname bindings must be deployed one by one to prevent Conflict (HTTP 429) errors.
#batchSize(1)
resource customHostnameWithoutSsl 'Microsoft.web/sites/hostnameBindings#2019-08-01' = [for fqdn in customHostnames: {
name: '${webAppService.name}/${fqdn}'
properties: {
siteName: webAppService.name
hostNameType: 'Verified'
sslState: 'Disabled'
}
}]
// Managed certificates can only be created once the hostname is added to the web app.
resource certificates 'Microsoft.Web/certificates#2022-03-01' = [for (fqdn, i) in customHostnames: {
name: '${fqdn}-${webAppName}'
location: location
properties: {
serverFarmId: appServicePlanResourceId
canonicalName: fqdn
}
dependsOn: [ ]
}]
// sslState and thumbprint can only be set once the managed certificate is created
#batchSize(1)
resource customHostname 'Microsoft.web/sites/hostnameBindings#2019-08-01' = [for (fqdn, i) in customHostnames: {
name: '${webAppService.name}/${fqdn}'
properties: {
siteName: webAppService.name
hostNameType: 'Verified'
sslState: 'SniEnabled'
thumbprint: certificates[i].properties.thumbprint
}
}]
Is there another way to create a single deployment template to deploy an Azure App Service with a managed SSL certificate for the custom hostname?
Updating the hostname binding in the same template also is not possible, as a resource can only exist once in a template.
To prevent this error, the resource can be deployed using a Bicep module (or ARM nested template).
Then the solution becomes this:
webApp.bicep
#description('The name of the App Service Plan that this web app will be deployed to.')
param appServicePlanResourceId string
#description('The location that the resource will be deployed to')
param location string = resourceGroup().location
#description('The custom hostnames that you wish to add.')
param customHostnames array = []
#description('Deploy hostnames without SSL binding before creating the certificate. Required when hostname is not present yet.')
param redeployHostnames bool = false
resource webAppService 'Microsoft.Web/sites#2020-12-01' = {
...
}
// hostname bindings must be deployed one by one to prevent Conflict (HTTP 429) errors.
#batchSize(1)
resource customHostnameWithoutSsl 'Microsoft.web/sites/hostnameBindings#2019-08-01' = [for fqdn in customHostnames: if (redeployHostnames) {
name: '${webAppService.name}/${fqdn}'
properties: {
siteName: webAppService.name
hostNameType: 'Verified'
sslState: 'Disabled'
}
}]
// certificates must be bound via module/nested template, because each resource can only occur once in every template
// in this case the hostnameBindings would occur twice otherwise.
module certificateBindings './bindCertificateToHostname.bicep' = {
name: '${deployment().name}-ssl'
params: {
appServicePlanResourceId: appServicePlanResourceId
customHostnames: customHostnames
location: location
webAppName: webAppService.name
}
dependsOn: customHostnameWithoutSsl
}
bindCertificateToHostname.bicep
param webAppName string
param location string
param appServicePlanResourceId string
param customHostnames array
// Managed certificates can only be created once the hostname is added to the web app.
resource certificates 'Microsoft.Web/certificates#2022-03-01' = [for (fqdn, i) in customHostnames: {
name: '${fqdn}-${webAppName}'
location: location
properties: {
serverFarmId: appServicePlanResourceId
canonicalName: fqdn
}
}]
// sslState and thumbprint can only be set once the managed certificate is created
#batchSize(1)
resource customHostname 'Microsoft.web/sites/hostnameBindings#2019-08-01' = [for (fqdn, i) in customHostnames: {
name: '${webAppName}/${fqdn}'
properties: {
siteName: webAppName
hostNameType: 'Verified'
sslState: 'SniEnabled'
thumbprint: certificates[i].properties.thumbprint
}
}]
One of the workaround you can follow to achieve the above requirement ;
To deploy an app service with SSL certificate for the custom domain you can follow the complete configuration and template which is suggested by #bmoore-msft on this GitHub sample:-
Sample template.json:-
"resources": [
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2019-08-01",
"name": "[variables('appServicePlanName')]",
"location": "[parameters('location')]",
"properties": {
"name": "[variables('appServicePlanName')]"
},
"sku": {
"name": "P1",
"tier": "Premium",
"size": "1",
"family": "P",
"capacity": "1"
}
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2019-08-01",
"name": "[parameters('webAppName')]",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Web/serverFarms', variables('appServicePlanName'))]"
],
"properties": {
"name": "[parameters('webAppName')]",
"serverFarmId": "[resourceId('Microsoft.Web/serverFarms', variables('appServicePlanName'))]"
}
},
{
"condition": "[variables('enableSSL')]",
"type": "Microsoft.Web/certificates",
"apiVersion": "2019-08-01",
"name": "[variables('certificateName')]",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', parameters('webAppName'))]"
],
"properties": {
"keyVaultId": "[parameters('existingKeyVaultId')]",
"keyVaultSecretName": "[parameters('existingKeyVaultSecretName')]",
"serverFarmId": "[resourceId('Microsoft.Web/serverFarms', variables('appServicePlanName'))]"
}
},
{
"type": "Microsoft.Web/sites/hostnameBindings",
"name": "[concat(parameters('webAppName'), '/', parameters('customHostname'))]",
"apiVersion": "2019-08-01",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Web/certificates', variables('certificateName'))]"
],
"properties": {
"sslState": "[if(variables('enableSSL'), 'SniEnabled', json('null'))]",
"thumbprint": "[if(variables('enableSSL'), reference(resourceId('Microsoft.Web/certificates', variables('certificateName'))).Thumbprint, json('null'))]"
}
}
NOTE:- I am not able to test it with custom domain due to of some provision issue with our account
For more information please refer this SO THREAD| How to configure an App Service Managed Certificate

Is it possible to use the Azure CLI for setting up a monitoring URL Ping test?

Is it possible to create programmatically using the Azure CLI an Azure Application Insights availability URL Ping Test?
I have checked the az cli application-insights documentation already (here: https://learn.microsoft.com/en-us/cli/azure/ext/application-insights/monitor/app-insights/component?view=azure-cli-latest) but I do not find anything related to the creation of a URL Ping Test.
There is no built-in cli command to do this, your option is to use az rest call the REST API - Web Tests - Create Or Update directly.
First, store a webtest.json file as below to your powershell execute location e.g. my location is PS C:\Users\Administrator>, I store the file in C:\Users\Administrator folder.
In this file, the centralus is the location of my appinsight, /subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/microsoft.insights/components/<appinsight-name> is the resource id of my appinsight, joytest1 is the name of the ping test, joyfun2 is the name of the appinsight, https://joyfun2.azurewebsites.net is the URL you want to test, please replace them with your values.
{
"location": "centralus",
"kind": "ping",
"tags": {
"hidden-link:/subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/microsoft.insights/components/<appinsight-name>": "Resource"
},
"properties": {
"Name": "joytest1",
"SyntheticMonitorId": "joytest1-joyfun2",
"Configuration": {
"WebTest": "<WebTest Name=\"joytest1\" Id=\"ec14f587-a3f6-40ac-8952-75c900e1d153\" Enabled=\"True\" CssProjectStructure=\"\" CssIteration=\"\" Timeout=\"120\" WorkItemIds=\"\" xmlns=\"http://microsoft.com/schemas/VisualStudio/TeamTest/2010\" Description=\"\" CredentialUserName=\"\" CredentialPassword=\"\" PreAuthenticate=\"True\" Proxy=\"default\" StopOnError=\"False\" RecordedResultFile=\"\" ResultsLocale=\"\"> <Items> <Request Method=\"GET\" Guid=\"a7247e6c-29c1-2451-f4c8-78afe599253d\" Version=\"1.1\" Url=\"https://joyfun2.azurewebsites.net\" ThinkTime=\"0\" Timeout=\"120\" ParseDependentRequests=\"False\" FollowRedirects=\"True\" RecordResult=\"True\" Cache=\"False\" ResponseTimeGoal=\"0\" Encoding=\"utf-8\" ExpectedHttpStatusCode=\"200\" ExpectedResponseUrl=\"\" ReportingName=\"\" IgnoreHttpStatusCode=\"False\" /> </Items> </WebTest>"
},
"Enabled": true,
"Frequency": 900,
"Timeout": 120,
"Kind": "ping",
"RetryEnabled": true,
"Locations": [
{
"Id": "us-fl-mia-edge"
},
{
"Id": "us-tx-sn1-azr"
},
{
"Id": "emea-au-syd-edge"
}
]
}
}
Then run the command below, also replace the values like above.
az rest --method PUT --uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<group-name>/providers/Microsoft.Insights/webtests/joytest1-joyfun2?api-version=2015-05-01" --headers 'Content-Type=application/json' --body `#webtest.json
It works fine on my side.
Check in the portal:
You can do it via deploying ARM template. Here is an example of a template. It creates an availability test and sets up an alert.
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"webTestLocation": {
"type": "String"
},
"componentName": {
"type": "String"
},
"testName": {
"type": "String"
},
"testEndpoint": {
"type": "String"
},
"testLocations": {
"type": "Array"
},
"numLocationsToAlertOn": {
"type": "Int"
},
"alertDescription": {
"type": "String"
}
},
"resources": [
{
"type": "microsoft.insights/webtests",
"apiVersion": "2015-05-01",
"name": "[parameters('testName')]",
"location": "[parameters('webTestLocation')]",
"tags": {
"[concat('hidden-link:',resourceId('microsoft.insights/components',parameters('componentName')))]": "Resource"
},
"properties": {
"SyntheticMonitorId": "[parameters('testName')]",
"Name": "[parameters('testName')]",
"Enabled": true,
"Frequency": 300,
"Timeout": 120,
"Kind": "ping",
"RetryEnabled": false,
"Locations": "[parameters('testLocations')]",
"Configuration": {
"WebTest": "[concat('<WebTest Name=\"',parameters('testName'),'\" Id=\"00000000-0000-0000-0000-000000000000\" Enabled=\"True\" CssProjectStructure=\"\" CssIteration=\"\" Timeout=\"120\" WorkItemIds=\"\" xmlns=\"http://microsoft.com/schemas/VisualStudio/TeamTest/2010\" Description=\"\" CredentialUserName=\"\" CredentialPassword=\"\" PreAuthenticate=\"True\" Proxy=\"default\" StopOnError=\"False\" RecordedResultFile=\"\" ResultsLocale=\"\"> <Items> <Request Method=\"GET\" Guid=\"a86e39d1-b852-55ed-a079-23844e235d01\" Version=\"1.1\" Url=\"',parameters('testEndpoint'),'\" ThinkTime=\"0\" Timeout=\"120\" ParseDependentRequests=\"False\" FollowRedirects=\"True\" RecordResult=\"True\" Cache=\"False\" ResponseTimeGoal=\"0\" Encoding=\"utf-8\" ExpectedHttpStatusCode=\"200\" ExpectedResponseUrl=\"\" ReportingName=\"\" IgnoreHttpStatusCode=\"False\" /> </Items> </WebTest>')]"
}
}
},
{
"type": "microsoft.insights/metricalerts",
"name": "[parameters('testName')]",
"apiVersion": "2018-03-01",
"location": "global",
"tags": {
"[concat('hidden-link:',resourceId('microsoft.insights/components',parameters('componentName')))]": "Resource",
"[concat('hidden-link:',resourceId('microsoft.insights/webtests',parameters('testName')))]": "Resource"
},
"properties": {
"description": "[parameters('alertDescription')]",
"enabled": true,
"severity": 3,
"windowSize": "PT5M",
"evaluationFrequency": "PT1M",
"criteria": {
"failedLocationCount": "[parameters('numLocationsToAlertOn')]",
"webTestId": "[resourceId('microsoft.insights/webtests/',parameters('testName'))]",
"componentId": "[resourceId('microsoft.insights/components/',parameters('componentName'))]",
"odata.type": "Microsoft.Azure.Monitor.WebtestLocationAvailabilityCriteria"
},
"actions": [
{
"actionGroupId": "[resourceId('microsoft.insights/actiongroups', 'IcM')]",
"webhookProperties": {}
}
],
"scopes": [ "[resourceId('microsoft.insights/webtests/',parameters('testName'))]", "[resourceId('microsoft.insights/components/',parameters('componentName'))]" ]
},
"dependsOn": [
"[resourceId('microsoft.insights/webtests', parameters('testName'))]"
]
}
]
}
Here is an example of how to do it using Powershell Az module:
$result = New-AzResourceGroupDeployment `
-Name $stampHealthCheckScaleTestName `
-ResourceGroupName $appInsightsResourceGroupName `
-Mode Incremental `
-TemplateFile $scriptRoot\ArmTemplates\HealthCheckScaleArmTemplate.json `
-webTestLocation $appInsightsComponentLocation `
-componentName $appInsightsComponentName `
-testName $stampHealthCheckScaleTestName `
-testEndpoint "https://$($customDomainName)/healthcheckscale/status" `
-testLocations $testLocations `
-numLocationsToAlertOn $numLocationsToAlertOn `
-alertDescription $alertDescription
Here is an example of generic ARM template deployment using az cli: https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/deploy-cli#inline-parameters
Here is another example to create a classic URL Ping Test with bicep-lang. Unfortunately, the format of the WebTest XML is not documented.
Pay attention to the hidden-link tag, which should point to your app insights resource.
var name = 'demo-url-ping-web-test'
var rg = 'rg-article'
var subscriptionId = '<your_subscription_id>'
var appInsightsName = 'appi-demo'
var id = guid('seed')
var timeout = 120
var frequency = 300
var guidId = guid('seed')
var method = 'GET'
var url = 'https://www.azureblue.io'
var expectedHttpStatusCode = 200
var version = '1.1'
var followRedirects = 'True'
var recordResults = 'True'
var cache = 'False'
var parseDependentRequests = 'False'
var ignoreHttpStatusCode = 'False'
resource urlPingWebTest 'Microsoft.Insights/webtests#2015-05-01' = {
name: name
location: 'westeurope'
tags: {
'hidden-link:/subscriptions/${subscriptionId}/resourceGroups/${rg}/providers/microsoft.insights/components/${appInsightsName}': 'Resource'
}
kind: 'ping'
properties: {
Configuration: {
WebTest: '<WebTest xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010" Name="${name}" Id="${id}" Enabled="True" CssProjectStructure="" CssIteration="" Timeout="${timeout}" WorkItemIds="" Description="" CredentialUserName="" CredentialPassword="" PreAuthenticate="True" Proxy="default" StopOnError="False" RecordedResultFile="" ResultsLocale=""> <Items> <Request Method="${method}" Guid="${guidId}" Version="${version}" Url="${url}" ThinkTime="0" Timeout="${timeout}" ParseDependentRequests="${parseDependentRequests}" FollowRedirects="${followRedirects}" RecordResult="${recordResults}" Cache="${cache}" ResponseTimeGoal="0" Encoding="utf-8" ExpectedHttpStatusCode="${expectedHttpStatusCode}" ExpectedResponseUrl="" ReportingName="" IgnoreHttpStatusCode="${ignoreHttpStatusCode}" /> </Items> </WebTest>'
}
Description: 'Runs a classic URL ping test'
Enabled: true
Frequency: frequency
Kind: 'ping'
Locations: [
{
Id: 'emea-nl-ams-azr'
}
{
Id: 'emea-ru-msa-edge'
}
{
Id: 'apac-hk-hkn-azr'
}
{
Id: 'latam-br-gru-edge'
}
{
Id: 'emea-au-syd-edge'
}
]
Name: name
RetryEnabled: true
SyntheticMonitorId: '${name}-id'
Timeout: timeout
}
}
You can deploy the template by using Azure CLI like so:
az deployment group create --name rollout01 --resource-group rg-article --subscription "your subscription" --template-file urlpingwebtest.bicep
If you are feeling brave you can also create a so-called Standard Test which is currently in preview but doesn't require the ominous WebTest XML string and works just well for me.
resource standardWebTest 'Microsoft.Insights/webtests#2018-05-01-preview' = {
name: 'demo-webtest'
location: 'westeurope'
tags: {
'hidden-link:/subscriptions/ade29918-737f-497e-8808-4bffda5cc46d/resourceGroups/rg-article/providers/microsoft.insights/components/appi-demo': 'Resource'
}
kind: 'standard'
properties: {
SyntheticMonitorId: 'demo-webtest-id'
Name: 'demo-webtest'
Description: null
Enabled: true
Frequency: 300
Timeout: 120
Kind: 'standard'
RetryEnabled: true
Locations: [
{
Id: 'emea-nl-ams-azr'
}
{
Id: 'emea-ru-msa-edge'
}
{
Id: 'apac-hk-hkn-azr'
}
{
Id: 'latam-br-gru-edge'
}
{
Id: 'emea-au-syd-edge'
}
]
Configuration: null
Request: {
RequestUrl: 'https://www.azureblue.io'
Headers: null
HttpVerb: 'GET'
RequestBody: null
ParseDependentRequests: false
FollowRedirects: null
}
ValidationRules: {
ExpectedHttpStatusCode: 200
IgnoreHttpsStatusCode: false
ContentValidation: null
SSLCheck: true
SSLCertRemainingLifetimeCheck: 7
}
}
}
You can read more about this on my blog post, which can be found here
For the benefit of anyone that finds this discussion, this seems to be working now that I test it:
az monitor app-insights web-test create `
--web-test-kind "standard" --enabled true `
--location $location `
--resource-group $rgName `
--name "health-check" --defined-web-test-name "health-check" `
--tags "hidden-link:$($appInsights.Id)=Resource" `
--http-verb "GET" --request-url "$appBaseUrl/health" `
--timeout 30 --frequency 300 --retry-enabled true `
--locations Id="emea-nl-ams-azr" --locations Id="us-fl-mia-edge"
I assume that this is what #ZakiMa was referring to.

Add Azure App Service to new VNet Integration preview

We want to connect an Azure App Service with our On Premise Network via the new VNet Integration (preview), which doesn't need any Point-to-Site Tunnel anymore.
We already achieved our goal via Azure Portal and now want to implement this in our DevOps Pipelines via ARM Template Deploy or Powershell.
ARM Template Deploy:
We generated the ARM Template from an exisiting App Service with new VNet Integration. Redeploy this Template doesn't add the new VNet Integration, but the old one (very strange):
{
"type": "Microsoft.Web/sites/virtualNetworkConnections",
"apiVersion": "2016-08-01",
"name": "[concat(parameters('sites_name'), parameters('subnet_name'))]",
"location": "West Europe",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', parameters('sites_name'))]"
],
"properties": {
"vnetResourceId": "[concat(parameters('virtualNetworks_externalid'), '/subnets/XXXXXXX')]",
"certThumbprint": null,
"certBlob": null,
"routes": null,
"resyncRequired": false,
"dnsServers": null,
"isSwift": true
}
}
Powershell Deploy:
Trying this code will add the old VNet Integration as well:
$propertiesObject = #{
"vnetResourceId" = "/subscriptions/$($subscriptionId)/resourceGroups/$($vnet.ResourceGroupName)/providers/Microsoft.Network/virtualNetworks/$($vnet.Name)/subnets/$($subnetNameToAdd)"
}
$virtualNetwork = New-AzureRmResource -Location $location -Properties $PropertiesObject -ResourceName "$($webAppName)/$($vnet.Name)" -ResourceType "Microsoft.Web/sites/virtualNetworkConnections" -ApiVersion 2016-08-01 -ResourceGroupName $resourceGroupName -Force
Is this another new feature from Microsoft which is just half implemented and semi available?
(yeah, its in preview, but since several month...)
this is how I got it to work:
{
"name": "vnet_name/subnet_name",
"type": "Microsoft.Network/virtualNetworks/subnets",
"apiVersion": "2018-08-01",
"location": "[resourceGroup().location]",
"properties": {
"addressPrefix": "10.0.1.0/24",
"delegations": [
{
"name": "delegation",
"properties": {
"servicename": "Microsoft.Web/serverfarms"
}
}
]
}
},
{
"name": "webappname/virtualNetwork",
"properties": {
"subnetResourceId": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'vnet_name', 'subnet_name')]",
"swiftSupported": true
},
"dependsOn": [
"[resourceId('Microsoft.Network/virtualNetworks/subnets', 'vnet_name', 'subnet_name')]"
],
"type": "Microsoft.Web/sites/config",
"location": "[resourceGroup().location]",
"apiVersion": "2018-02-01"
}

Import a database using AzureRM Powershell

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.

Resources