Reputation: 163
I am attempting to deploy a resource with Terraform using an ARM template. I will give some simple sample code below that demonstrates the issue. I realize the code below is deploying a storage account and can be done in Terraform without an ARM template, but I am just providing a piece of simple code to demonstrate the problem. My real code is deploying a SQL Managed Instance which is much more complicated and likely just confuses the question.
Here is the main.tf:
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "2.41.0"
}
}
}
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "resourcegroup" {
location = "North Central US"
name = "test"
}
resource "azurerm_resource_group_template_deployment" "deployment" {
name = "test-${formatdate("YYYYMMDDhhmmss", timestamp())}"
resource_group_name = azurerm_resource_group.resourcegroup.name
deployment_mode = "Incremental"
template_content = file("template.json")
parameters_content = templatefile("parameters.json",
{
name = "vwtuvnpplzgelqey"
supportsHttpsTrafficOnly = true
}
)
}
Here is the ARM template.json file:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"name": {
"type": "string"
},
"supportsHttpsTrafficOnly": {
"type": "bool"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-04-01",
"name": "[parameters('name')]",
"location": "northcentralus",
"sku": {
"name": "Standard_LRS"
},
"kind": "StorageV2",
"properties": {
"supportsHttpsTrafficOnly": "[parameters('supportsHttpsTrafficOnly')]"
}
}
]
}
Here is the ARM parameters.json file:
{
"name": {
"value": "${name}"
},
"supportsHttpsTrafficOnly": {
"value": "${supportsHttpsTrafficOnly}"
}
}
If I run terraform apply on this with just the name
as a parameter and hard-code supportsHttpsTrafficOnly
to a true value (e.g. "supportsHttpsTrafficOnly": true
), it works perfectly and the storage account is successfully deployed. As soon as I change it to use the parameter for supportsHttpsTrafficOnly, it fails with the following error:
: Code="InvalidTemplate" Message="Deployment template validation failed: 'Template parameter JToken type is not valid. Expected 'Boolean'. Actual 'String'. Please see https://aka.ms/resource-manager-parameter-files for usage details.'." AdditionalInfo=[{"info":{"lineNumber":1,"linePosition":213,"path":"properties.template.parameters.supportsHttpsTrafficOnly"},"type":"TemplateViolation"}]
This error indicates that the value for supportsHttpsTrafficOnly is a string when it should be a boolean. I don't understand this error as I am clearly defining the type as bool in the template.json file.
What am I missing so that the value is interpreted as a bool value instead of a string?
Upvotes: 0
Views: 1216
Reputation: 163
It turns out this is actually an easy fix, if not an obvious one.
Apparently all parameters need to be defined as string and then use the ARM template conversion functions to convert to the correct type.
In the template.json, we would have this in the parameters section:
“supportsHttpsTrafficOnly”: {
“type”: “string”
}
And then in the resources section, convert the string to a boolean using a template conversion:
"properties": {
"supportsHttpsTrafficOnly": "[bool(parameters('supportsHttpsTrafficOnly'))]"
}
Then finally in main.tf, pass the value as a string:
parameters_content = templatefile("parameters.json",
{
name = "vwtuvnpplzgelqey"
supportsHttpsTrafficOnly = "true"
}
Upvotes: 1
Reputation: 425
Per documentation: https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/template-syntax#data-types
When specifying boolean and integer values in your template, don't surround the value with quotation marks. Start and end string values with double quotation marks.
What you have in your code is "value": "${supportsHttpsTrafficOnly}"
. This probably interpreted as "value": "true"
when you pass a var into it.
Switching to "value": ${supportsHttpsTrafficOnly}
should fix your issue.
But if I were you, I would go for the heredoc way, which is also the one used in the example of in the provider docs: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group_template_deployment
So use:
...
template_content = <<TEMPLATE
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
...
TEMPLATE
}
instead of using a different .json file.
Upvotes: 0