使用Terraform部署ARM模板会导致数据类型不匹配



我正在尝试使用ARM模板使用Terraform部署资源。我将在下面给出一些简单的示例代码来演示这个问题。我意识到下面的代码是在部署一个存储帐户,并且可以在没有ARM模板的情况下在Terraform中完成,但我只是提供了一段简单的代码来演示这个问题。我真正的代码是部署一个SQL托管实例,它要复杂得多,可能只是混淆了问题。

这是主.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
}
)
}

这是ARM template.json文件:

{
"$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')]"
}
}
]
}

这是ARM parameters.json文件:

{
"name": {
"value": "${name}"
},
"supportsHttpsTrafficOnly": {
"value": "${supportsHttpsTrafficOnly}"
}
}

如果我只使用name作为参数并将supportsHttpsTrafficOnly硬编码为真值(例如"supportsHttpsTrafficOnly": true(来运行terraform apply,则它可以完美地工作,并且成功地部署了存储帐户。一旦我将其更改为使用supportsHttpsTrafficOnly的参数,它就会失败,并出现以下错误:

: 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"}]

此错误表示supportsHttpsTrafficOnly的值是一个字符串,而它应该是布尔值。我不理解这个错误,因为我在template.json文件中将类型定义为bool。

我缺少什么,从而将值解释为布尔值而不是字符串?

事实证明,这实际上是一个简单的修复方法,如果不是显而易见的话。

显然,所有参数都需要定义为字符串,然后使用ARM模板转换函数转换为正确的类型。

在template.json中,我们将在参数部分中有这样的内容:

“supportsHttpsTrafficOnly”: {
“type”: “string”
}

然后在参考资料部分,使用模板转换将字符串转换为布尔值:

"properties": {
"supportsHttpsTrafficOnly": "[bool(parameters('supportsHttpsTrafficOnly'))]"
}

最后在main.tf中,将值作为字符串传递:

parameters_content = templatefile("parameters.json",
{
name = "vwtuvnpplzgelqey"
supportsHttpsTrafficOnly = "true"
}

根据文档:https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/template-syntax#data-类型

在模板中指定布尔值和整数值时,不要用引号将值括起来。开始和结束字符串值带有双引号。

您的代码中包含的是"value": "${supportsHttpsTrafficOnly}"。当您将var传递给它时,这可能被解释为"value": "true"

切换到"value": ${supportsHttpsTrafficOnly}应该可以解决您的问题。

但如果我是你,我会选择heredoc方式,这也是提供者文档中的示例中使用的方式:https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group_template_deployment

所以使用:

...
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
}

而不是使用不同的.json文件。

相关内容

最新更新