Following Azure Advisory Recommendation, I want to enable diagnostic settings for my app services. I added the following ARM template but keeps getting error:
Deployment template validation failed: 'The template resource 'pr-datap-cf0-config-as/Microsoft.Insights/service' for type 'providers/diagnosticSettings' at line '218' and column '41' has incorrect segment lengths. A nested resource type must have identical number of segments as its resource name. A root resource type must have segment length one greater than its resource name. Please see https://aka.ms/arm-template/#resources for usage details.'. (Code:InvalidTemplate)
I think my type has 2 segments while name has 3. But what is the type value for diagnosticSettings of an app service?
My ARM template is as follows:
{
"type": "providers/diagnosticSettings",
"apiVersion": "2016-09-01",
"name": "[concat(parameters('appServiceName'), '/Microsoft.Insights/service')]",
"location": "[parameters('location')]",
"dependsOn": [
"[parameters('appServiceName')]"
],
"properties": {
"storageAccountId": "[parameters('diagnosticStorageAccountId')]",
"workspaceId": "[parameters('workspaceId')]",
"metrics": [
{
"category": "AllMetrics",
"enabled": true,
"retentionPolicy": {
"enabled": true,
"days": "[parameters('diagnosticLogsRetentionInDays')]"
}
}
],
"logs": [
{
"category": "AppServiceAuditLogs",
"enabled": true,
"retentionPolicy": {
"enabled": true,
"days": "[parameters('diagnosticLogsRetentionInDays')]"
}
}
]
}
According to my knowledge, there is no type like providers/diagnosticSettings. It should be like Microsoft.Insights/diagnosticSettings or Microsoft.KeyVault/vaults/providers/diagnosticSettings, here are the example templates. And to set the diagnostic setting for the app service, you can take a look at another issue here. And you can also take a look at Enable diagnostics logging for apps in Azure App Service.
Related
I was following the repo for separate parameter file to each env as defined in the https://github.com/Azure/bicep/discussions/4586
I tried the separate parameters file for dev, stage, prod but the value assignment in main module variable remains flagged by intelligence even though it exists same param exist in the respective parameter file.
Other approach I tried is loadjson variable, but it does not show auto completion for items under subnet block as it stopes right after value.
Maybe I am overthinking and not applying the correct approach, Perhaps I should ignore intellisense and try deploying by applying parameter and hope it will auto pick correct value during the deployment param check.
Here is my parameter file and the same value applies to each env param json.
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"department": {
"value": "finance"
},
"saAccountCount": {
"value": 1
},
"vmCount": {
"value": 1
},
"locationIndex": { //idenx 1 = app server, 2=AD, 3=Tool server, 4= dchp server
"value": 1
},
"appRoleIndex": { //idenx 1 = westus2, 2= westus, 3= eastus, 4=centralus, 5=uswest3
"value": 1
},
"appRole": {
"value": {
"Applicatoin Server": "ap",
"Active Directory": "dc",
"Tool server": "tool",
"DHCP server": "dhcp"
}
},
"environment": {
"value": "dev"
},
"addressPrefixes": {
"value": [
"172.16.0.0/20"
]
},
"dnsServers": {
"value": [
"1.1.1.1",
"4.4.4.4"
]
},
"locationList": {
"value": {
"westus2": "azw2",
"westus": "azw",
"Eastus": "aze",
"CentralUS": "azc",
"westus3": "azw3"
}
},
"subnets": {
"value": [
{
"name": "frontend",
"subnetPrefix": "172.16.2.0/24",
"delegation": "Microsoft.Web/serverfarms",
"privateEndpointNetworkPolicies": "disabled",
"serviceEndpoints": [
{
"service": "Microsoft.KeyVault",
"locations": [
"*"
]
},
{
"service": "Microsoft.Web",
"locations": [
"*"
]
}
]
},
{
"name": "backend",
"subnetPrefix": "172.16.3.0/24",
"delegation": "Microsoft.Web/serverfarms",
"privateEndpointNetworkPolicies": "enabled",
"serviceEndpoints": [
{
"service": "Microsoft.KeyVault",
"locations": [
"*"
]
},
{
"service": "Microsoft.Web",
"locations": [
"*"
]
},
{
"service": "Microsoft.AzureCosmosDB",
"locations": [
"*"
]
}
]
}
]
}
}
}
You appear to be attempting to deploy an Azure Resource Management (ARM) template using a parameter file.
The parameter file is used to pass values to the ARM template during deployment. The parameter file must use the same types as the ARM template and can only include values for the ARM template's parameters.
You will receive an error if the parameter file contains extra parameters that do not match the ARM template's parameters.
In the same deployment process, you can use both inline parameters and a local parameter file. If you specify a parameter's value in both the local parameter file and inline, the inline value takes priority.
Refer to create a parameter file of an ARM template
About the different parameters file for dev, stage, and prod, it's likely that the parameter file is not correctly linked to the ARM template.
You can deploy the ARM template with the parameter file to determine if it will automatically select the proper value during the deployment parameter check.
Regarding the loadjson variable, it is possible that the loadjson variable is not properly formatted.
You can double-check the loadjson variable's format to ensure it's proper.
After a workaround on this, I created a sample parameter.json file for a webapp to deploy in a production environment and that worked for me.
Note: Alternatively, You can use az deployment group create with a parameters file and deploy into Azure to avoid these conflicts.
This is how the chunk of the ARM template looks:
{
"type": "Microsoft.ApiManagement/service/diagnostics/loggers",
"apiVersion": "2018-01-01",
"name": "[concat(variables('gatewayName'), '/applicationinsights/', variables('gatewayName'))]",
"dependsOn": [
"[resourceId('Microsoft.ApiManagement/service/diagnostics', variables('gatewayName'), 'applicationinsights')]",
"[resourceId('Microsoft.ApiManagement/service', variables('gatewayName'))]"
],
"properties": {
"loggerType": "applicationInsights",
"credentials": {
"instrumentationKey": "[reference(resourceId('Microsoft.Insights/components', variables('appInsights')), '2014-04-01').InstrumentationKey]"
},
"isBuffered": true,
"resourceId": "[variables('appInsights')]"
}
},
For two days our ARM template deployment is failing with the error:
{"status":"Failed","error":{"code":"DeploymentFailed","message":"At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/DeployOperations for usage details.","details":[{"code":"BadRequest","message":"{\r\n \"error\": {\r\n \"code\": \"MethodNotAllowedInPricingTier\",\r\n \"message\": \"Method not allowed in this pricing tier\",\r\n \"details\": null\r\n }\r\n}"}]}}
Although the error states the pricing tier, there were no changes in the template.
Verbatim google search result shows that the resource existed before as the first result item.
The documentation does not mention it anymore in the diagnostics section.
GitHub, though, remembers the resource but mentions different properties within the object:
"service_diagnostics_loggers": {
"type": "object",
"properties": {
"apiVersion": {
"type": "string",
"enum": [
"2018-01-01"
]
},
"name": {
"oneOf": [
{
"type": "string",
"pattern": "(^[\\w]+$)|(^[\\w][\\w\\-]+[\\w]$)",
"maxLength": 80
},
{
"$ref": "https://schema.management.azure.com/schemas/common/definitions.json#/definitions/expression"
}
],
"description": "Logger identifier. Must be unique in the API Management service instance."
},
"type": {
"type": "string",
"enum": [
"Microsoft.ApiManagement/service/diagnostics/loggers"
]
}
},
"required": [
"apiVersion",
"name",
"type"
],
"description": "Microsoft.ApiManagement/service/diagnostics/loggers"
}
It looks like the resource was removed from the ARM template infrastructure silently. What is wrong my analysis?
diagnostics/loggers resource does exist in 2018-01-01 API version: https://github.com/Azure/azure-rest-api-specs/blob/main/specification/apimanagement/resource-manager/Microsoft.ApiManagement/stable/2018-01-01/apimdiagnostics.json
After that though it was removed and replaced by loggerId property on diagnostic entity itself: https://github.com/Azure/azure-rest-api-specs/blob/main/specification/apimanagement/resource-manager/Microsoft.ApiManagement/stable/2019-01-01/definitions.json#L1771
We'll check why older API version doesn't seem to work, meanwhile you could try migrating to a newer API version.
I'm deploying an ARM template that take care of creating an app service plan.
I've exported the template from the existing plan and parametrized for our needs.
sometimes we get several errors on deplying
microsoft.insights/components/ProactiveDetectionConfigs
the errors are of
Value cannot be null. Parameter name: componentEnv
if we retry many times the operations until all the ProactiveDetectionConfigs resources are deployed we can finally complete the deployment.
Currently we have the following resources
microsoft.insights/components
microsoft.insights/webtests
Microsoft.Portal/dashboards
Microsoft.Web/serverfarms
microsoft.insights/components/ProactiveDetectionConfigs
Microsoft.Web/sites
I cannot figure out if i'm not considering some dependencies (currently is dependent on microsoft.insights/components and Microsoft.Web/sites) or if that kind of resource is necessary at all
thanks
To deploy the ProactiveDetectionConfigs into ARM template use the below code in your template
{
"type": "Microsoft.Insights/components/ProactiveDetectionConfigs",
"apiVersion": "2018-05-01-preview",
"name": "string",
"location": "string",
"properties": {
"CustomEmails": [ "string" ],
"Enabled": "bool",
"RuleDefinitions": {
"Description": "string",
"DisplayName": "string",
"HelpUrl": "string",
"IsEnabledByDefault": "bool",
"IsHidden": "bool",
"IsInPreview": "bool",
"Name": "string",
"SupportsEmailNotifications": "bool"
},
"SendEmailsToSubscriptionOwners": "bool"
}
}
Check the ProactiveDetectionConfigs link for more information.
I had the same issue and it was transient. It worked fine in the next several deployments with no other changes.
I have a VMSS which I deployed using ARM templates. This is the networkProfile block under VMSS resource section.
"networkProfile": {
"networkInterfaceConfigurations": [
{
"name": "[variables('nicName')]",
"properties": {
"primary": true,
"ipConfigurations": [
{
"name": "[concat(variables('VMSSName'), '-ipconfig')]",
"properties": {
"subnet": {
"id": "[variables('subnetRef')]"
},
"applicationGatewayBackendAddressPools": "[variables('AppGatewayBackendAddressPool')]"
}
}
]
}
}
]
},
In Variable section, if I use resourceId() function and provide values from parameters then it does not apply the configuration in VMSS. for example:
"AppGatewayBackendAddressPool": "[resourceId(parameters('VirtualNetworkResourceGroup'),'Microsoft.Network/applicationGateways/backendAddressPools', parameters('ApplicationGatewayName'), parameters('BackendAddressPool'))]",
I've also tried adding parameters('SubscriptionName') but the result is same.
"AppGatewayBackendAddressPool": "[resourceId(parameters('SubscriptionName') ,parameters('VirtualNetworkResourceGroup'),'Microsoft.Network/applicationGateways/backendAddressPools', parameters('ApplicationGatewayName'), parameters('BackendAddressPool'))]",
When I declare variable like below then it applies backendAddressPool configuration in Networking -> Load Balancing.
"AppGatewayBackendAddressPool": [
{ "id": "/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.Network/applicationGateways/<applicationGatewayName>/backendAddressPools/<backendAddressPool>" }
],
Similar I'm doing with subnetRef like below and that is working fine.
"subnetRef": "[resourceId(parameters('VirtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks/subnets', parameters('VirtualNetworkName'), parameters('SubnetName'))]",
I want to parametrize the deployment by defining separate parameters.json file so I can attach applicationGatewayBackendAddressPools with different virtual machine scale sets.
This is how I achieved it by following Ked Mardemootoo answer.
IP configuration section under networkProfile of VMSS resource.
"ipConfigurations": [
{
"name": "[concat(variables('VMSSName'), '-ipconfig')]",
"properties": {
"subnet": {
"id": "[variables('subnetRef')]"
},
"applicationGatewayBackendAddressPools": [
{ "id": "[concat(parameters('AapplicationGatewayExternalid'), '/backendAddressPools/', parameters('BackendAddressPool'))]" }
]
}
}
]
Template file parameters:
"BackendAddressPool": {
"type": "string",
"metadata": {
"description": "Backend pool to host blue/green vmss."
}
},
"AapplicationGatewayExternalid": {
"type": "string",
"metadata": {
"description": "Application Gateway Id."
}
}
Now, ARM template is calling and referencing applicationGatewayBackendAddressPools attribute dynamically under VMSS' resource section.
I have these two parameters in parameters.json file where I can define values according to environment.
"BackendAddressPool": {
"value": "<backendPoolName>"
},
"AapplicationGatewayExternalid": {
"value": "/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.Network/applicationGateways/<ApplicationGatewayName>"
}
Overriding template variables in release pipeline vars:
overriding template vars
Defining in pipeline vars
pipeline var
You seem to be missing the concat in the variables. Looking at the raw json on my end, this is how it's configured. See if you can do something similar, and convert the subnet name and backend address pool to variables.
"ipConfigurations": [
{
"name": "ip-vmss-name",
"properties": {
"primary": true,
"subnet": {
"id": "[concat(parameters('virtualNetworks_vnet_externalid'), '/subnets/snet-vm')]"
},
"privateIPAddressVersion": "IPv4",
"applicationGatewayBackendAddressPools": [
{
"id": "[concat(parameters('applicationGateways_agw_1_externalid'), '/backendAddressPools/be-addr-pool-vmss-1')]"
}
]
}
}
]
Nothing seems wrong with your variables/parameters call but applicationGatewayBackendAddressPools is not a valid attribute for neither VMSS nor Application Gateway.
You can do it check AKS and Application Gateway documentations. I achieve the same goal by setting backendAddressPools, which is in Application Gateway section, in different parameters.json files.
I have a situation where I want to only add a property to a VM if a condition is met. For example if I want to add an availability set property to a machine then do this : Below I ONLY what to execute the availability set statement if a condition is TRUE, can you do this in an ARM template? eg if a value is true then do this line, if not skip?
{
"name": "[parameters('ComputerName')]",
"type": "Microsoft.Compute/virtualMachines",
"location": "[parameters('location')]",
"apiVersion": "2017-03-30",
"dependsOn": [
"[resourceId('Microsoft.Network/networkInterfaces', variables('1stNicName'))]",
"[resourceId('Microsoft.Network/networkInterfaces', variables('2ndicName'))]"
],
"tags": {
"displayName": "[parameters('ComputerName')]"
},
"properties":
{
"availabilitySet": {
"id": "[resourceId('Microsoft.Compute/availabilitySets',variables('availabilitySetName'))]"
},
"hardwareProfile": {
"vmSize": "[parameters('serverVmSize')]"
},
"osProfile": {
"computerName": "[parameters('serverName')]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPassword')]"
},
As of this week (1st August 2017), ARM templates now have an IF function that can be used for variables, properties and resource parameters. It works like most other ARM functions, with syntax like:
[if(condition, true value, false value)]
The example in the documentation does exactly what you are asking, adds (or doesn't add) an availbility set to a VM:
"apiVersion": "2016-03-30",
"type": "Microsoft.Compute/virtualMachines",
"properties": {
"availabilitySet": "[if(equals(parameters('availabilitySet'),'yes'), variables('availabilitySet'), json('null'))]",
...
}
Note that the True value, the availiblity set to use, is stored as a variable rather than inline in the if statement.
"variables": {
...
"availabilitySetName": "availabilitySet1",
"availabilitySet": {
"id": "[resourceId('Microsoft.Compute/availabilitySets',variables('availabilitySetName'))]"
}
},
There is no direct way of doing this. you can use conditional to choose a value, but you cannot not set a value or pass in null (unless you want to define 2 variables for `properties').
so you can just define 2 vm resources that are exactly the same except for the property in question (so availabilitySet). One would have it and the other one would not. And you would use "condition": expression in both resources. Condition should equals to false or true to work. There are several functions in ARM templates that can evaluate input and return true or false.
Reference:
https://samcogan.com/conditions-in-arm-templates-the-right-way/
"variables": {
"loadBalancerBackendAddressPools": [
{
"id": "[parameters('lbBackendAddressPool')]"
}
]
},
Believe i have found a workable way to avoid defining two entire VM definitions for an availability set. following are from my own testing in an arm template i have made with extensive conditional controls.
this works:
"availabilitySet": {
"id": "[resourceId('Microsoft.Compute/availabilitySets',parameters('availabilitySetName'))]"
}
this does not:
"availabilitySet": "[if(equals(parameters('availabilitySet'),'yes'), variables('availabilitySet'), json('null'))]",
this also does not work due to ID being 'null':
"availabilitySet": {
"id": "[if(equals(parameters('availabilitySet'),'yes'), variables('availabilitySet'), json('null'))]"
}
I have added the following variable and parameter:
"parameters": {
"SpotInstance": {
"type": "bool",
"defaultValue": false,
"allowedValues": [
true,
false
],
"metadata": {
"description": "Should the VM be deployed as a low cost Spot Instance, this will deploy without attaching the Availability Set."
}
}
},
"variables": {
"AvailibilitySet": {
"On":{
"id":"[resourceId('Microsoft.Compute/availabilitySets/',variables('ASName'))]"
},
"Off":"[json('null')]"
}
}
then used this logic on the availability set assignment:
"availabilitySet": "[if(equals(parameters('SpotInstance'),bool('true')),variables('AvailibilitySet').Off,variables('AvailibilitySet').On)]",
if you do not define id as a property of "AvailabilitySet" this can be null, if you Do however it cannot be null.
When i try the same for loadbalancer backend pool i get errors:
12:21:49 - [ERROR] "message": "Cannot deserialize the current JSON object (e.g.
12:21:49 - [ERROR] {\"name\":\"value\"}) into type 'Microsoft.WindowsAzure.Networking.Nrp.Frontend
12:21:49 - [ERROR] .Contract.Csm.Public.ResourceReferenceHashSet`2[Microsoft.WindowsAzure.Networki
12:21:49 - [ERROR] ng.Nrp.Frontend.Contract.Csm.Public.LoadBalancerBackendAddressPool,Microsoft.Wi
12:21:49 - [ERROR] ndowsAzure.Networking.Nrp.Frontend.Contract.Csm.Public.NetworkInterfaceIpConfig
12:21:49 - [ERROR] uration]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize
12:21:49 - [ERROR] correctly.\r\nTo fix this error either change the JSON to a JSON array (e.g.
12:21:49 - [ERROR] [1,2,3]) or change the deserialized type so that it is a normal .NET type
12:21:49 - [ERROR] (e.g. not a primitive type like integer, not a collection type like an array
12:21:49 - [ERROR] or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute
12:21:49 - [ERROR] can also be added to the type to force it to deserialize from a JSON
variables
"availabilitySet": {
"id": "[resourceId('Microsoft.Compute/availabilitySets',parameters('availabilitySetName'))]"
},
"loadBalancerBackendAddressPools": {
"id": "[resourceId('Microsoft.Network/loadBalancers',parameters('LoadBalancername'))]"
},
"loadBalancerBackendAddressPools": "[if(equals(parameters('DeployavailabilitySet'),'yes'), variables('loadBalancerBackendAddressPools'), json('null'))]",