Search code examples
azureazure-devopsazure-keyvaultazure-rm-template

ARM template error Bad JSON content found in the request


I am trying to deploy an ARM template using the Azure DevOps release pipeline. Azure KeyVault is one of the resources in the template. the deployment is successful when I use the Powershell script. however, when Azure DevOps Release pipeline is used, deployment fails with error "Bad JSON content found in the request"

The key vault resource definition is as below.

{
  "type": "Microsoft.KeyVault/vaults",
  "apiVersion": "2018-02-14",
  "name": "[parameters('keyVaultName')]",
  "location": "[parameters('location')]",
  "tags": {
    "displayName": "KeyVault"
  },
  "properties": {
    "enabledForDeployment": "[parameters('enabledForDeployment')]",
    "enabledForTemplateDeployment": "[parameters('enabledForTemplateDeployment')]",
    "enabledForDiskEncryption": "[parameters('enabledForDiskEncryption')]",
    "tenantId": "[parameters('tenantId')]",
    "accessPolicies": [],
    "sku": {
      "name": "[parameters('skuName')]",
      "family": "A"
    }
  }
}

Update: I suspected that it could be because of tenant id and hardcoded the tenant id to test. But still no luck.


Solution

  • According to the log, you are specifying the override parameters in the task. That's why you are using the ARM template I provided, but still facing the Bad request error. Because in the task logic, the script which in ARM files is the request body of the API. And we use this API to create a resource you specified in azure. For detailed task logic described, you can refer my previous answer.

    The parameter definition in the ARM template is correct, but now, the error caused by the override parameters specified:

    enter image description here

    More specifically, the error is because of the subscription().tenantId in your parameter override definition.

    You can try to use Write-Host subscription().tenantId to get its value and print out by using Azure powershell task. You will see that it could not get any thing. One word, this can only used in Json file instead of used in task.

    So now, because of no value get from this expression, also you have override the previous value which defined in the JSON file. It will lack the key parameter value(tenantId) in the request body when the task is going to create a azure resource with API.


    There has 2 solution can solve it.

    1. Do not try to override the parameters which its value is using expression.

    Here I just mean the parameter that relevant with Azure subscription. Most of the expression could not be compiled in the Azure ARM deploy task.

    2. If you still want to override these special parameters with the special expression in the task.

    If this, you must add one task firstly, to get the tenantId from that. Then pass it into the ARM deploy task.

    You can add Azure Powershell task by using the following sample script:

    Write-Output "Getting tenantId using Get-AzureRmSubscription..."
    
    $subscription = (Get-AzureRmSubscription -SubscriptionId $azureSubscriptionId)
    
    Write-Output "Requested subscription: $azureSubscriptionId"
    
    $subscriptionId = $subscription.Id
    $subscriptionName = $subscription.Name
    $tenantId = $subscription.tenantId
    
    Write-Output "Subscription Id: $subscriptionId"
    Write-Output "Subscription Name: $subscriptionName"
    Write-Output "Tenant Id: $tenantId"
    Write-Host  "##vso[task.setvariable variable=TenantID;]$$tenantId"
    

    Then in the next task, you can use $(TenantID) to get its value.

    Here you can refer to this two excellent blog: Blog1 and Blog2


    I still recommend you to use the first solution since the volume of the pipeline will increase and complicate if choosing the second solution.