我需要将terra类型的map变量从terraform传递到powershell userdata脚本,并能够在powershell脚本中访问映射的键值对。谢谢
userdata.tf
data "template_file" "user_data" {
template = "${file("${path.module}/init.ps1")}"
vars = {
environment = var.env
# I want to pass the values as shown below
hostnames = {"dev":"devhost","test":"testhost","prod":"prodhost"}
}
}
init.ps1
$hostnames = "${hostnames}"
$environment = "${environment}"
if ($environment -eq "dev"){
# print the value of the dev key in the hostname map here
}
答案 0 :(得分:1)
不推荐使用template_file数据源。
注意:在Terraform 0.12和更高版本中,the
templatefile
function提供了一种内置机制,用于从文件渲染模板。除非使用的是Terraform 0.11或更早版本,否则请使用该函数。
首选templatefile function,这就是我的解决方案改用它的原因。
在任何一种情况下,模板var仅支持 map(string)。值必须是字符串。 JSON可以对任意树结构进行编码,包括将主机名映射为字符串。
在您的Terraform代码中,使用jsonencode将主机名编码为JSON。
userdata.tf:
locals {
user_data = templatefile("${path.module}/init.ps1" ,{
environment = var.env
# I want to pass the values as shown below
hostnames = jsonencode({"dev":"devhost","test":"testhost","prod":"prodhost"})
})
}
在PowerShell中,使用the ConvertFrom-Json cmdlet从JSON解码主机名。
init.ps1:
$hostnames = '${hostnames}' | ConvertFrom-Json
$environment = "${environment}"
if ($environment -eq "dev"){
# print the value of the dev key in the hostname map here
}
更新:如注释中所述,-AsHashtable
不一定会起作用,因为它是在PowerShell 6.0中添加的。 Windows 10和Windows Server 2016包含PowerShell 5.1。如果您的地图的键({"name" = "foo" ; "Name" = "bar"}
)仅区分大小写,则需要安装PowerShell 6.0或更高版本并使用ConvertFrom-Json -AsHashtable
。
答案 1 :(得分:1)
要在模板结果中包含集合值,您必须决定如何将其表示为字符串,因为模板结果始终是字符串。
PowerShell通过the ConvertFrom-Json
cmdlet支持JSON编码,因此JSON字符串可能是一个不错的选择,尽管它带来了一些挑战,因为您必须确保将JSON字符串作为有效的PowerShell表达式写入结果中,这意味着我们还必须应用PowerShell转义。
将所有内容放在一起,您可以像这样调整模板:
$hostnames = '${replace(jsonencode(hostnames), "'", "''")}' | ConvertFrom-Json
$environment = '${replace(environment, "'", "''")}'
if ($environment -eq "dev"){
Write-Output $hostnames["dev"]
}
jsonencode
函数产生给定值的JSON编码版本。然后,上面的代码将结果传递给replace
,这样结果中的任何'
字符都将以''
的形式转义,然后将整个结果放在单引号'
中确保有效的PowerShell语法。
呈现模板的结果将是这样的:
$hostnames = '{"dev":"devhost","test":"testhost","prod":"prodhost"}' | ConvertFrom-Json -AsHashtable
$environment = 'dev'
if ($environment -eq "dev"){
Write-Output $hostnames["dev"]
}
您似乎正在使用Terraform 0.12,因此应使用the templatefile
function而不是template_file
数据源。该功能更好,因为它可以接受任何类型的值,而数据源只能接受字符串值(因为它是为Terraform 0.11设计的)。
要使用templatefile
,请找到您之前引用data.template_file.user_data的位置,并在其中使用templatefile
函数:
templatefile("${path.module}/init.ps1", {
environment = var.env
hostnames = {"dev":"devhost","test":"testhost","prod":"prodhost"}
})
然后您可以删除data "template_file" "user_data"
块,因为此templatefile
函数调用将替换它。