通过包含其名称的变量动态引用 Terraform 数据资源



我正在尝试在 Terraform 数据分配中连接一个声明的变量以构建动态调用。

具有以下代码:

# Policy 1
data "aws_iam_policy_document" "1_s3_access_policy" {
statement {
effect = "Allow"
actions = [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
]
resources = [
"arn:aws:s3:::1_s3_access_policy/*",
"arn:aws:s3:::1_s3_access_policy",
]
principals {
type        = "AWS"
identifiers = ["arn:aws:iam::67435677645:user/d2c-user-us-west-1"]
}
}
}
# policy 2
data "aws_iam_policy_document" "2_s3_access_policy" {
statement {
effect = "Allow"
actions = [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
]
resources = [
"arn:aws:s3:::2_s3_access_policy/*",
"arn:aws:s3:::2_s3_access_policy",
]
principals {
type        = "AWS"
identifiers = ["arn:aws:iam::67435677645:user/d2c-user-us-west-1"]
}
}
}
# Policy 3
...
variable "s3_bucket_names" {
type    = list(any)
default = ["1_s3_access_policy", "2_s3_access_policy", "3_s3_access_policy"]
}
module "platform-cloud" {
source              = "./module"
count               = length(var.s3_bucket_names) //count will be 3
bucket_name         = var.s3_bucket_names[count.index]
sse_algorithm       = "aws:kms"
iam_policy_document =  data.aws_iam_policy_document.${var.s3_bucket_names[count.index]}.json
}

它失败并出现错误:

Error: Invalid character

on main.tf line 10, in module "platform-cloud":

iam_policy_document = data.aws_iam_policy_document.${var.s3_bucket_names[count.index]}.json

This character is not used within the language.

有没有办法在地形数据调用中连接变量?

Terraform无法以您尝试的方式动态查找资源,因为这意味着在评估之前不会确定资源依赖关系,但 Terraform 需要在计算任何表达式之前知道正确的依赖关系顺序。

但是,您可以通过额外的步骤来满足动态选择资源的用例,即使用随后用于选择每个资源的键创建映射:

locals {
bucket_policies = {
s3_access_policy_1 = data.aws_iam_policy_document.s3_access_policy_1
s3_access_policy_2 = data.aws_iam_policy_document.s3_access_policy_2
s3_access_policy_3 = data.aws_iam_policy_document.s3_access_policy_3
}
}
module "platform-cloud" {
source = "./module"
count  = length(var.s3_bucket_names) //count will be 3
bucket_name         = var.s3_bucket_names[count.index]
sse_algorithm       = "aws:kms"
iam_policy_document = local.bucket_policies[var.s3_bucket_names[count.index]].json
}

我已将数据资源的名称更改为s3_access_policy_1而不是1_s3_access_policy,因为 Terraform 不允许资源名称以数字开头。Terraform 尚未报告该错误消息,因为您有语法错误,但解决语法错误会暴露命名错误。

请注意,现在module.platform-cloudiam_policy_document指的是整个local.bucket_policies,而整个又依赖于所有三个数据资源。因此,Terraform 明白,在评估该模块参数之前,它必须评估所有这三个数据资源,从而生成正确的计算顺序。


虽然与您的问题没有直接关系,但我建议您阅读何时使用for_each而不是count来决定在module "platform-cloud"块中使用for_each是否更好,而不是count

通常,您将按如下方式执行此操作:

iam_policy_document =  data.aws_iam_policy_document[var.s3_bucket_names[count.index]].json

确切的细节将取决于如何定义data.aws_iam_policy_document。但遗憾的是,您的问题中没有提供此类信息。

最新更新