Terraform - 将类型对象作为参数传递给 Azure 模板部署

Terraform - Passing type Object as a parameter to Azure Template Deployment

我想通过为 Terraform 提供 Azure ARM 模板来使用 Terraform 来配置 Azure AD 域服务,这是因为 Terrafrom 本身不支持配置 Azure AD 域服务。

我已经导出了 ARM 模板及其参数,其中一个参数称为 "notificationSettings",它是一种 Object 类型,如下所示:

    "notificationSettings": {
        "value": {
            "notifyGlobalAdmins": "Enabled",
            "notifyDcAdmins": "Enabled",
            "additionalRecipients": []
        }
    }

其他参数都是strings,我可以毫无问题的传递,例如:

"apiVersion" = "2017-06-01"

我试过将此对象传递给如下参数:

"notificationSettings" = [{
                "notifyGlobalAdmins" = "Enabled"
            "notifyDcAdmins" ="Enabled"
            "additionalRecipients" = []
}]

然而,当我执行 terrafrom apply 时,terrafrom 抱怨说:

Inappropriate value for attribute "parameters": element "notificationSettings": string required.

如何将对象类型的参数传递给 template body

我还尝试使用 parameters_body 选项将整个 ARM json 参数作为文件提供给 terrafrom ,如下所示:

parameters_body = "${file("${path.module}/temp/params.json")}"

但是,我在执行 terrafrom 脚本时遇到以下错误:

The request content was invalid and could not be deserialized: 'Error converting value "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#" to type 'Microsoft.WindowsAzure.ResourceStack.Frontdoor.Data.Definitions.DeploymentParameterDefinition'. Path 'properties.parameters.$schema', line 1, position 2952.'.

下面是 params.json 文件:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "apiVersion": {
            "value": "2017-06-01"
        },
        "sku": {
            "value": "Standard"
        "location": {
            "value": "westus"
        },
        "notificationSettings": {
            "value": {
                "notifyGlobalAdmins": "Enabled",
                "notifyDcAdmins": "Enabled",
                "additionalRecipients": []
            }
        },
        "subnetName": {
            "value": "xxxx"
        },
        "vnetName": {
            "value": "xxxx"
        },
        "vnetAddressPrefixes": {
            "value": [
                "10.0.1.0/24"
            ]
        },
        "subnetAddressPrefix": {
            "value": "10.0.1.0/24"
        },
        "nsgName": {
            "value": "xxxxx"
        }
    }
}

有一种方法可以将任意数据结构从 Terraform 传递到 ARM。

在 azure_template_deployment 提供程序

中有两种方法可以将数据传递到 ARM 模板
  • 使用 parameters 块,仅限于字符串参数
  • 使用 parameters_body 块,这几乎是任意的 JSON。

我发现使用参数块的最简单方法是创建一个具有我需要的结构的局部变量,然后对其调用 jsonencode。我还喜欢将 ARM 模板保存在一个单独的文件中,并通过 file() 调用将其拉入,从而降低 terraform 的复杂性。

locals {
  location = "string"
  members = [
    "array",
    "of",
    "members"
  ]
  enabled = true
  tags = {
    "key" = "value",
    "simple" = "store"
  }

  # this is the format required by ARM templates
  parameters_body = {
    location = {
      value = "${local.location}"
    },
    properties = {
      value = {
        users = {
          members = "${local.members}"
        }
        boolparameter = "${local.enabled}"
      }
    }
    tags = {
      value = "${module.global.tags}"
    }
  }
}

resource "azurerm_template_deployment" "sample" {
  name = "sample"
  resource_group_name = "rg"
  deployment_mode = "Incremental"
  template_body = "${file("${path.module}/arm/sample_arm.json")}"
  parameter_body = "${jsonencode(local.parameters_body)}"
}

我发现的唯一警告是 bool 参数作为字符串传递,因此在 ARM 参数部分将它们声明为字符串,然后使用 ARM 函数转换为 bool

"parameters: {
  "boolParameter": {
     "type": "string"
  }
},
"variables": {
  "boolVariable": "[bool(parameters('boolParameter'))]"
},
"resources": [
  ...
  "boolArm": "[variables('boolVariable')]",
  ...
]