Tony
Tony

Reputation: 1694

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?

Upvotes: 1

Views: 2408

Answers (1)

Brando Zhang
Brando Zhang

Reputation: 27997

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:

enter image description here

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:

enter image description here

Upvotes: 1

Related Questions