如何读取从地形形式传递到 Powershell 用户数据脚本的 Map 类型的变量的值?



>我需要将 map 类型的变量从 terraform 传递到 powershell 用户数据脚本,并能够在 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"}
}
}

初始化.ps1

$hostnames = "${hostnames}"
$environment = "${environment}"
if ($environment -eq "dev"){
# print the value of the dev key in the hostname map here
}

不建议使用template_file数据源。

注意 在 Terraform 0.12 及更高版本中,templatefile函数提供了从文件呈现模板的内置机制。请改用该函数,除非您使用的是 Terraform 0.11 或更早版本。

模板文件函数是首选,这就是我的解决方案使用它的原因。

无论哪种情况,模板变量都只支持map(string(。这些值必须是字符串。JSON 可以将任意树结构编码,包括主机名映射为字符串。

在您的地形代码中,使用 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中,使用ConvertFrom-Json cmdlet从JSON解码主机名。

初始化.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

为了在模板结果中包含集合值,您必须决定如何将其表示为字符串,因为模板结果始终是字符串。

PowerShell 支持通过ConvertFrom-Jsoncmdlet 进行 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,因此您应该使用templatefile函数而不是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函数调用会替换它。

相关内容

  • 没有找到相关文章

最新更新