Azure CLI Extensions: exported dashboard template.json "does not contain the property 'location'" error - json

I'm getting this error:
<_io.TextIOWrapper name='C:\\Users\\david\\source\\repos\\azurePortalInfrastruct\\ExportedTemplate-example-resources\\template.json' mode='r' encoding='cp1252'> does not contain the property 'location'
Which may be down to the way the template.json file has been put together.
My issue is similar to:
Azure CLI unable to create portal dashboards from templates
I followed this to a now closed github issue: Azure CLI unable to create portal dashboards from templates #16356
Following the advice from the developer. I used the following command (which generated the error):
az portal dashboard import --name "testDashboard" --resource-group "example-resources_copy" `
>> --input-path "C:\Users\david\source\repos\azurePortalInfrastruct\ExportedTemplate-example-resources\template.json"
The file template.json was exported from my portal. I have checked it. It has lines 13-16:
"type": "Microsoft.Portal/dashboards",
"apiVersion": "2020-09-01-preview",
"name": "[parameters('dashboards_a9dc12e1_3aae_431d_b935_81dd5ea20bd8_dashboard_name')]",
"location": "westus",
Regarding a similar command the developer has said:
In az portal dashboard create, the --input-path is the path to properties json file instead of full template.
My export from portal dashboard consisted of two files.
template.json
parameters.json
The file template.json contains a properties section on line 20 (which follows the location line 16) But I didn't get a separate properties.json file in my export.
The developer goes on to say:
If you want to create a dashboard with full template, should use the command az portal dashboard import. Also, you need to update the location value in your sample Json.
I can get it working with the sample json code sample used for the github issue #16356
{
"properties": {
"lenses": {
"0": {
"order": 0,
"parts": {}
}
},
"metadata": {
"model": {
"timeRange": {
"value": {
"relative": {
"duration": 24,
"timeUnit": 1
}
},
"type": "MsPortalFx.Composition.Configuration.ValueTypes.TimeRange"
}
}
}
},
"name": "TestDashboard",
"type": "Microsoft.Portal/dashboards",
"location": "westus",
"tags": {
"hidden-title": "My Test Dashboard"
},
"apiVersion": "2015-08-01-preview"
}
But this is sample is nothing like the JSON ARM code I exported from my existing Azure Portal dashboard.
Any suggestions appreciated.

Related

How can I retrieve the query key for Bing Maps API for Enterprise in an Azure Resource Group Template?

I am working on an ARM template that deploys an entire infrastructure from scratch:
The resource group
App Service plans
Application Insights
an so forth...
At some point I get to the part where I write the scripts for deploying my App Service (for hosting and deploying my web app later on) to my resource group. Prior to that I have my BingMaps API deployed in the same script.
I am stuck at the part where I am setting the Application Settings for my web app:
"type": "Microsoft.Web/sites",
"properties": {
"siteConfig": {
"appSettings": [
{
"name": "SomeKey",
"value": "SomeValue"
}, //rest of the code omitted
I would like to know how could I retrieve my BING MAPS query key within an ARM template?
I have tried, and have a feeling that this might be close to it, something like:
"value": "[reference(resourceId('Microsoft.BingMaps/mapApis', variables('bingMapsName')), '2016-08-18').queryKey]"
Anybody who has done this before? Many thanks in advance! Cheers
If you want to access query key in your ARM template for your web app setting, I would suggest you to use something like below:
{
"name": "appsettings",
"type": "config",
"apiVersion": "2015-08-01",
"dependsOn": [
"[concat('Microsoft.Web/sites/', variables('webSiteName'))]"
],
"tags": {
"displayName": "WebAppSettings"
},
"properties": {
"key1": "[parameter('AppSetting_Key1_Value')]",
"key2": "value2"
}
}
and then in your template.Parmeter.jso file , you can declare the key AppSetting_Key1_Value with the value of your Bing maps query key.
Specify the Parameter Value
After the Parameter has been added to the ARM Template and it’s being used to populate an Application Setting, the final step is to define the Parameter value within the ARM Templates Parameter file used for deployments. In the Azure Resource Group project template in Visual Studio the Parameters file for the default deployment is the file that ends with “.parameters.json”.
Here’s a screenshot of the “WebSite.parameters.json” file created in the previous articles in this series with the “AppSetting_Key1_Value” Parameter set to a value:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"hostingPlanName": {
"value": "WebApp1HostingPlan"
},
"WebApplication1PackageFolder": {
"value": "WebApplication1"
},
"WebApplication1PackageFileName": {
"value": "package.zip"
},
"WebApp_ConnString1": {
"value": "Server=myServerAddress;Database=myDataBase;Trusted_Connection=True;"
},
"AppSetting_Key1_Value": {
"value": "Template Value 1"
}
}
}
for security complaint solution , you can move all your secure key and connection string to Azure key vault if you are not comfortable to have keys in param file.
This should work. Hope it helps.

Deploy Cloudera cluster on azure FAILED , JSON/ARM template issue

I m trying to install cloudera on azure using the link below https://github.com/Azure/azure-quickstart-templates/tree/master/cloudera-on-centos It gave me a few errors, below deploy cloudera on centos Required property 'resources' not found in JSON
I solved it. BUT I m now stuck at some point. "message": "Deployment template validation failed: 'The template 'copy' definition at line '0' and column '0' is missing a copy input value.
I use copy for resources, not for properties, there is no need for input value.
{
"type": "Microsoft.Network/publicIPAddresses",
"name": "[concat(variables('publicIPAddressName'), copyIndex())]",
"location": "[parameters('location')]",
"copy": [{
"name": "publicIPLoop",
"count": "[parameters('vmCount')]"
}],
"properties": {
"publicIPAllocationMethod": "Dynamic",
"dnsSettings": {
"domainNameLabel": "[concat(parameters('dnsNamePrefix'), '-dn', copyIndex())]"
}
}
}
copy should look like this:
"copy": {
"name": "publicIPLoop",
"count": "[parameters('vmCount')]"
},
its an object, not an array
THANKS A LOT for your response,
Initially there was no bracket , it gave me another error:
"message": "Deployment template validation failed: 'The template resource 'master-node' at line '493' and column '9' is not valid: The template function 'copyIndex' is not expected at this location. The function can only be used in a resource with copy specified. Please see https://aka.ms/arm-copy for usage details.. Please see https://aka.ms/arm-template-expressions for usage details.'."
I googled it, and I saw the post
copyindex() error in arm template
I put the brackets, to make it an array, and now it asks me for input, which does not make sense, according to
https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-multiple

Using a local Open API Standard file to to create an ARM template for a web service

I am working on an old web service where I generate the rest endpoints documentation that comply with OAS standards using a custom tool. Using this OAS json file I can deploy the API to Azure API Managements services through the portal and it all works fine. However, I need to automate this process and hence need to use ARM templates to deploy all web services to Azure APIM. I have been looking into the examples provided https://learn.microsoft.com/en-us/azure/templates/microsoft.apimanagement/service/apis but just can't seem to wrap my head around how to use a local OAS.json file or a file in github.
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for all resources."
}
}
},
"variables": {
"apiManagementServiceName": "price-capture"
},
"resources": [
{
"apiVersion": "2018-01-01",
"type": "Microsoft.ApiManagement/service/apis",
"name": "[variables('apiManagementServiceName')]",
"properties": {
"displayName": "Service display Name",
"apiRevision": "1",
"description": "API description",
//need help since it's not a swagger url
//wondering if there is a way to ref a local file like the option
//provided in the portal when we register api's manually.
"serviceUrl": "----",
"path": "----",
"protocols": [
"https"
],
"isCurrent": true,
"apiVersion": "v1",
"apiVersionDescription": "apiVersionDescription"
}
}
]
}
You can deploy and configure an entire API on API Management via ARM templates, but you cannot use a local file to provide the OpenApi/Swagger.
In your case the OpenApi/Swagger needs to be publicly accessible so the resource manager can read from it, so if the Github URL is freely accessible it should work.
I typically store the OpenApi/Swagger to a storage account and use the SAS token to access it from the ARM template.
You can check out this blog for details on automating API deployment in APIM:
https://blog.eldert.net/api-management-ci-cd-using-arm-templates-linked-template/
You can deploy the API using an Azure Resource Manager template of type Microsoft.ApiManagement/service/apis, and to use an Open API / swagger definition you need to specify the contentValue and and contentFormat parameters of the template
{
"name": "awesome-api-management/petstore",
"type": "Microsoft.ApiManagement/service/apis",
"apiVersion": "2018-06-01-preview",
"properties": {
"path": "petstore"
"contentValue": "petstore swagger file contents here", // or it's URL
"contentFormat": "swagger-json", // or swagger-link-json if externally available
}
}
I don't think it's possible to deploy the APIs configs via templates.
I've been trying to figure this out myself but I'm pretty sure you can't include the actual APIs you want in the service.
From what I can tell, you can't do that with the GIT repo either because that needs authentication that is manually created in the portal
I think the only thing you can automate with the ARM template is the actual API Management service and then you need to use the Azure API to add and configure the APIs on it.
However, I have yet to figure out how to do that myself.
I actually have a service ticket open to get help on that.
The API has changed slightly so this works:
The yaml file (calculatorApiFile) needs to be uploaded first to a blob storage, but this can be done as part of the deployment pipeline
{
"type": "Microsoft.ApiManagement/service/apis",
"apiVersion": "2019-01-01",
"name": "[concat(parameters('service_name'), '/b12b1d5ab8204cg6b695e3e861fdd709')]",
"dependsOn": [
"[resourceId('Microsoft.ApiManagement/service', parameters('service_name'))]"
],
"properties": {
"displayName": "Calculator",
"apiRevision": "1",
"description": "A simple Calculator ",
"path": "calc",
"value": "[concat(parameters('containerUri'), parameters('calculatorApiFile'), parameters('containerSasToken'))]",
"format": "openapi-link",
"protocols": [
"https"
],
"isCurrent": true
}
}
I figured out the answer ..all I had to do was write an azure function that fetches the oas.yaml file from a private github repository.
"variables":{
"swagger_json":"[concat(parameters('url_of_azurefunctionwithaccesskey'),'&&githuburi='parameter('raw_url'),'&githubaccesstoken=',parameter('personalaccesstoken')]"
},
"resources": [
{
"type": "Microsoft.ApiManagement/service/apis",
"name": "[concat(parameters('apimName') ,'/' ,parameters('serviceName'))]",
"apiVersion": "2018-06-01-preview",
"properties": {
"apiRevision": "[parameters('apiRevision')]",
"path": "pricecapture",
"contentValue": "[variables('swagger_json')]",
"contentFormat": "openapi-link"
}
}]
The Azure function that I had to write was something like this:
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System.IO;
using System.Text;
public static async Task<HttpResponseMessage> Run(HttpRequest req, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
var gitHubUri = req.Query["githuburi"];
var gitHubAccessToken = req.Query["githubaccesstoken"];
var encoding = Encoding.ASCII;
if (string.IsNullOrEmpty(gitHubUri))
{
var errorcontent = new StringContent("please pass the raw file content URI (raw.githubusercontent.com) in the request URI string", Encoding.ASCII);
return new HttpResponseMessage
{
StatusCode = HttpStatusCode.BadRequest,
Content = errorcontent
};
}
else if (string.IsNullOrEmpty(gitHubAccessToken))
{
var errorcontent = new StringContent("please pass the GitHub personal access token in the request URI string", Encoding.ASCII);
return new HttpResponseMessage
{
StatusCode = HttpStatusCode.BadRequest,
Content = errorcontent
};
}
else
{
var strAuthHeader = "token " + gitHubAccessToken;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3.raw");
client.DefaultRequestHeaders.Add("Authorization", strAuthHeader);
var response = await client.GetAsync(gitHubUri);
return response;
}
}
If you load your YAML into a variable, that can be passed to the ARM template and be passed as the value:
deploy.bat:
SETLOCAL EnableDelayedExpansion
set API_DEPLOYMENT=<deployment name>
set API_GROUP=<deployment group>
set API=<api file path.yml>
set OPENAPI=
for /f "delims=" %%x in ('type %API%') do set "OPENAPI=!OPENAPI!%%x\n"
call az deployment group create -n %API_DEPLOYMENT% -g %API_GROUP% --mode Complete -f deploy.json -p openApi="!OPENAPI!"
ENDLOCAL
deploy.json (note the use of replace)
...
{
"type": "Microsoft.ApiManagement/service/apis",
"apiVersion": "2020-12-01",
"name": "[variables('apiName')]",
"properties": {
"path": "[variables('service')]",
"apiType": "http",
"displayName": "[variables('apiDisplayName')]",
"format": "openapi",
"value": "[replace(parameters('openApi'), '\\n', '\n')]"
},
...
},
...

Azure RM Templates. How to upload assets automatically with VS instead of fetching them from GitHub

I would like to be able to deploy a complex ARM template that utilizes DSC extensions and nested templates from my local Visual Studio.
The example is set to download assets from GitHub:
https://github.com/Azure/azure-quickstart-templates/tree/master/active-directory-new-domain-ha-2-dc
What changes do I have to make that I can tie the assets to my local Visual Studio project and use them instead of downloading them from GitHub?
Here is the strip down version of the template responsible for downloading:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
...
"adPDCVMName": {
"type": "string",
"metadata": {
"description": "The computer name of the PDC"
},
"defaultValue": "adPDC"
},
"assetLocation": {
"type": "string",
"metadata": {
"description": "The location of resources such as templates and DSC modules that the script is dependent"
},
"defaultValue": "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/active-directory-new-domain-ha-2-dc"
}
...
},
"variables": {
...
"adPDCModulesURL": "[concat(parameters('assetLocation'),'/DSC/CreateADPDC.ps1.zip')]",
"adPDCConfigurationFunction": "CreateADPDC.ps1\\CreateADPDC",
...
},
"resources": [
...
{
"name": "[parameters('adPDCVMName')]",
"type": "Microsoft.Compute/virtualMachines",
...
"resources": [
{
"name": "[concat(parameters('adPDCVMName'),'/CreateADForest')]",
"type": "Microsoft.Compute/virtualMachines/extensions",
...
"properties": {
...
"settings": {
"ModulesUrl": "[variables('adPDCModulesURL')]",
"ConfigurationFunction": "[variables('adPDCConfigurationFunction')]",
...
}
}
}
}
}
]
}
]
}
Do the following in your 'Azure Resource Group' project in Visual Studio:
Copy the files to your project in Visual Studio using the same
directory structure. So a DSC directory and a nestedtemplates directory with
the files that belong there.
Set the files in the directories as content (azuredeploy.json is not needed, only the files you are referring to). This way the powershell script to deploy the templates will upload it to a storage account in azure.
Make it possible to use files uploaded to the storage account. In this case the template that you are referring to is not using the common
namingconvention. So you need to change it a bit:
Change azuredeploy.json: Change the name of parameter
assetLocation to _artifactsLocation.
Second: Add a parameter
_artifactsLocationSasToken as securestring. These 2 parameters will be filled automatically by the powershell script in Visual Studio.
part of the azuredeploy.json:
"parameters": {
"_artifactsLocation": {
"type": "string",
"metadata": {
"description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated."
}
},
"_artifactsLocationSasToken": {
"type": "securestring",
"metadata": {
"description": "The SAS token to access the storage account"
}
},
Because the original azuredeploy.json is not using the _artifactsLocationSasToken parameter. You need to change all variables where the assetlocation is used. Change all variables so it uses the _artifactsLocation and add a part to use the _artifactsLocationSasToken.
one sample:
"vnetTemplateUri": "[concat(parameters('_artifactsLocation'),'/nestedtemplates/vnet.json', parameters('_artifactsLocationSasToken'))]",
After you changed all variables. You can deploy the template from Visual Studio using the resources in your project instead of from github.

How to set the application log in an Azure webapp using Azure resource manager

Does anyone know how to set the below diagnostic settings on an Azure Web App using Azure Resource Manager (Powershell or JSON).
Using .json I can only find these settings
"requestTracingEnabled": true, /* Failed request tracing, aka 'freb' */
"httpLoggingEnabled": true, /* IIS logs (aka Web server logging) */
"logsDirectorySizeLimit": 40, /* 40 MB limit for IIS logs */
"detailedErrorLoggingEnabled": true, /* Detailed error messages */
Which turns on web server logging to filesystem but NOT Application Logging or to blob storage.
With Powershell this command only seems to work with ASM as it does not find Non-classic storage accounts given to it
Enable-AzureWebsiteApplicationDiagnostic
Any help would be appreciated. We are currently using Azure Powershell 0.9.8
Regards
The Azure Resource Manager (ARM) template json section for configuring Application Log (Blob) and Web Server Logging (Storage) based on your screenshot above is as shown below:
{
"apiVersion": "2015-08-01",
"name": "logs",
"type": "config",
"dependsOn": [
"[resourceId('Microsoft.Web/Sites', parameters('siteName'))]"
],
"properties": {
"applicationLogs": {
"azureBlobStorage": {
"level": "Information",
"sasUrl": "<Your Azure Blob Storage Account SAS Url>",
"retentionInDays": null
}
},
"httpLogs": {
"azureBlobStorage": {
"sasUrl": "<Your Azure Blob Storage Account SAS Url>",
"retentionInDays": null,
"enabled": true
}
},
"failedRequestsTracing": {
"enabled": true
},
"detailedErrorMessages": {
"enabled": true
}
}
}
References: AzureWebsitesSamples/ARMTemplates/WebAppManyFeatures.json
Hope this answer your question and help solving your issue.
Please let me know if you need further help or clarifications.
If you browse an existing webapp in Resource Explorer you'll find a config/logs section that looks something like this:
{
"id": "/subscriptions/.../config/logs",
"name": "logs",
"type": "Microsoft.Web/sites/config",
"location": "North Central US",
"properties": {
"applicationLogs": {
"fileSystem": {
"level": "Off"
},
"azureBlobStorage": {
"level": "Information",
"sasUrl": "...",
"retentionInDays": 14
}
},
...
}
I believe you can use this format in your json template to configure the logging. (This section would be a sibling to the config/web section which contains the settings mentioned in the question.)
Note though that the config/logs section is not described in the System.Web schema, and so I'd imagine is not currently supported by MS at this time. I'm pretty sure I've tried it and seen it work though.
I didn't find how to set it in the template at the first provision. But it turned out to be easy after resources were provisioned. Please see answer at https://stackoverflow.com/a/51617949/511144 for the actual script to do it that uses Set-AzureRmResource