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

时间:2020-01-26 16:22:28

标签: terraform terraform-provider-azure

我想通过给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会抱怨并说:

属性“参数”的值不合适:元素 “ notificationSettings”:必需的字符串。

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

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

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

但是,执行terrafrom脚本时出现了Followig错误:

请求内容无效,无法反序列化:“错误 转换价值 “ https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#” 输入 'Microsoft.WindowsAzure.ResourceStack.Frontdoor.Data.Definitions.DeploymentParameterDefinition'。 路径'properties.parameters。$ schema',第1行,位置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"
        }
    }
}

1 个答案:

答案 0 :(得分:4)

有一种方法可以将任意数据结构从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)}"
}

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

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