正确使用 Terraform 外部数据源
Properly using Terraform External Data Source
我正在使用来自 Azure bash 云 shell 的 Terraform。我正在尝试将外部数据源添加到我的 Terraform 配置文件中,该文件将使用 az cli
查询 Microsoft 上的 virtualip
对象。Web/hostingEnvironment 模板部署。
AZ CLI 命令行:
az resource show --ids /subscriptions/<subscription Id>/resourceGroups/my-ilbase-rg/providers/Microsoft.Web/hos
tingEnvironments/my-ilbase/capacities/virtualip
当 运行 来自命令行时的输出:
{
"additionalProperties": {
"internalIpAddress": "10.10.1.11",
"outboundIpAddresses": [
"52.224.70.119"
],
"serviceIpAddress": "52.224.70.119",
"vipMappings": []
},
"id": null,
"identity": null,
"kind": null,
"location": null,
"managedBy": null,
"name": null,
"plan": null,
"properties": null,
"sku": null,
"tags": null,
"type": null
}
在我的 Terraform 配置中,我为 --ids
值创建了一个变量:
variable ilbase_resourceId {
default = "/subscriptions/<subscription Id>/resourceGroups/my-ilbase-rg/providers/Microsoft.Web/hostingEnvironments/my-ilbase/capacities/virtualip"
}
然后我以这种方式构建数据源:
data "external" "aseVip" {
program = ["az", "resource", "show", "--ids", "${var.ilbase_resourceId}"]
}
当我执行配置时,出现以下错误:
data.external.aseVip: data.external.aseVip: command "az" produced invalid JSON: json: cannot unmarshal object into Go value of type string
知道我做错了什么吗?
当您在会话中工作时,该命令将会成功。我想当你从你的 shell 中 运行 时,你已经完成了 az login
。当 terraform 执行您的命令时,它不使用您现有的会话。您需要创建一个 PS1 脚本,在其中提示您登录,或者在其中提供您的凭据,以便您的请求能够成功。
无论您的选择是什么,请考虑到脚本应该具有的唯一输出是 JSON。如果任何其他命令向输出添加某些内容(例如,当您登录时,您有一个包含有关您的订阅的信息的输出)那么您将遇到相同的错误,因为输出不是正确的 JSON。您需要将这种额外的输出通过管道传输到 Out-Null
,使它们成为 "silent",然后将您从请求中收到的 JSON 写入输出。
希望对您有所帮助。
我发现问题在于 Terraform 外部数据源尚无法处理命令返回的复杂结构。我能够通过在脚本的开头添加一个 AZ CLI 命令块来解决这个问题,我用来部署获取 IP 地址并将其作为变量传递到 Terraform 配置的应用程序网关。下面是我正在使用的脚本块:
ilbase_virtual_ip=$(
az resource show \
--ids "/subscriptions/$subscription_id/resourceGroups/$ilbase_rg_name/providers/Microsoft.Web/hostingEnvironments/$ilbase_name/capacities/virtualip" \
--query "additionalProperties.internalIpAddress"
)
我正在使用来自 Azure bash 云 shell 的 Terraform。我正在尝试将外部数据源添加到我的 Terraform 配置文件中,该文件将使用 az cli
查询 Microsoft 上的 virtualip
对象。Web/hostingEnvironment 模板部署。
AZ CLI 命令行:
az resource show --ids /subscriptions/<subscription Id>/resourceGroups/my-ilbase-rg/providers/Microsoft.Web/hos
tingEnvironments/my-ilbase/capacities/virtualip
当 运行 来自命令行时的输出:
{
"additionalProperties": {
"internalIpAddress": "10.10.1.11",
"outboundIpAddresses": [
"52.224.70.119"
],
"serviceIpAddress": "52.224.70.119",
"vipMappings": []
},
"id": null,
"identity": null,
"kind": null,
"location": null,
"managedBy": null,
"name": null,
"plan": null,
"properties": null,
"sku": null,
"tags": null,
"type": null
}
在我的 Terraform 配置中,我为 --ids
值创建了一个变量:
variable ilbase_resourceId {
default = "/subscriptions/<subscription Id>/resourceGroups/my-ilbase-rg/providers/Microsoft.Web/hostingEnvironments/my-ilbase/capacities/virtualip"
}
然后我以这种方式构建数据源:
data "external" "aseVip" {
program = ["az", "resource", "show", "--ids", "${var.ilbase_resourceId}"]
}
当我执行配置时,出现以下错误:
data.external.aseVip: data.external.aseVip: command "az" produced invalid JSON: json: cannot unmarshal object into Go value of type string
知道我做错了什么吗?
当您在会话中工作时,该命令将会成功。我想当你从你的 shell 中 运行 时,你已经完成了 az login
。当 terraform 执行您的命令时,它不使用您现有的会话。您需要创建一个 PS1 脚本,在其中提示您登录,或者在其中提供您的凭据,以便您的请求能够成功。
无论您的选择是什么,请考虑到脚本应该具有的唯一输出是 JSON。如果任何其他命令向输出添加某些内容(例如,当您登录时,您有一个包含有关您的订阅的信息的输出)那么您将遇到相同的错误,因为输出不是正确的 JSON。您需要将这种额外的输出通过管道传输到 Out-Null
,使它们成为 "silent",然后将您从请求中收到的 JSON 写入输出。
希望对您有所帮助。
我发现问题在于 Terraform 外部数据源尚无法处理命令返回的复杂结构。我能够通过在脚本的开头添加一个 AZ CLI 命令块来解决这个问题,我用来部署获取 IP 地址并将其作为变量传递到 Terraform 配置的应用程序网关。下面是我正在使用的脚本块:
ilbase_virtual_ip=$(
az resource show \
--ids "/subscriptions/$subscription_id/resourceGroups/$ilbase_rg_name/providers/Microsoft.Web/hostingEnvironments/$ilbase_name/capacities/virtualip" \
--query "additionalProperties.internalIpAddress"
)