以Terraform代码连接文件路径前缀和文件名

问题描述 投票:2回答:1

我正在尝试在具有Terraform的AWS中创建策略。

variable "path" {
    type = "string"
}

variable "policies" {
    type = list(object ({
     name = string
     plcyfilename = string
     asmplcyfilename = string
     desc = string
     ownner = string}))
    default = []
}

resource "aws_iam_policy" "policy" {
  count = length(var.policies)
  name =  lookup(var.policies[count.index], "name")
  policy = file(lookup(var.policies[count.index], concat("var.path","plcyfilename")))
  description = "Policy for ${lookup(var.policies[count.index], "desc")}"
}

这就是我的tfvar的样子:

path = "./../t2/scripts/"

policies =  [

{name = "cwpolicy", plcyfilename = "cw.json" , asmplcyfilename ="csasm.json", desc ="vpcflowlogs", ownner ="vpc"},

]

执行此操作时抛出的错误是这样的:

Error: Invalid function argument

  on main.tf line 13, in resource "aws_iam_policy" "policy":
  13:   policy = file(lookup(var.policies[count.index], "${concat("${var.path}","plcyfilename")}"))

Invalid value for "seqs" parameter: all arguments must be lists or tuples; got
string.

我正在使用Terraform 0.12。

如果我将变量更改为具有完整的文件路径,则可以正常工作:plcyfilename=./../t2/scripts/cw.json

但是我想从文件名中分离出文件路径。

有人可以指出我要去哪里。

loops terraform concat terraform-provider-aws
1个回答
0
投票

The concat function用于连接列表,而不用于连接字符串。

要在Terraform中连接字符串,我们使用concat

template interpolation syntax

由于您的策略集合不是顺序很重要的序列,因此建议您也将其更改为使用 policy = file("${var.path}/${var.policies[count.index].policy_filename}") ,这将确保Terraform使用策略名称字符串而不是使用位置中的位置来跟踪策略列表:

resource for_each

在这种情况下,for_each变量被重新定义为映射,因此,您现在将每个策略的名称显示为映射内的键而不是属性之一:

variable "policies" {
  type = map(object({
    policy_filename        = string
    assume_policy_filename = string
    description            = string
    owner                  = string
  }))
  default = {}
}

resource "aws_iam_policy" "policy" {
  for_each = var.policies

  name        = each.key
  policy      = file("${var.path}/${each.value.policy_filename}")
  description = "Policy for ${each.value.description}"
}

因为policies值是策略映射,资源块内的 policies = { cw = { policy_filename = "cw.json" assume_policy_filename = "csasm.json" description = "vpcflowlogs" owner = "vpc" } # ... } 是策略名称,for_each是表示该策略的对象,所以结果表达式更易于阅读和理解。

通过使用each.key,我们将使Terraform创建像each.value而不是for_each之类的资源实例地址,因此从地图中添加和删除元素将导致Terraform从资源中添加和删除相应实例,而不是像在您的示例中那样尝试就地更新实例以遵守列表顺序。

© www.soinside.com 2019 - 2024. All rights reserved.