我正在尝试创建一个tpl文件。因此我可以为我角色提供访问多个k8s群集的权限。但是我得到了一个元组错误。
当tpl文件有一些插值时,我们应该如何将变量传递给tpl文件?也请让我知道这个错误是什么意思,以及我哪里错了。
Terraform版本: 0.12.28
locals.tf
federated = [
"xxxxxxxxxxxxxxxx",
"yyyyyyyyyyyyyyyy"
]
federatedList1 = [for oidc in local.federated : "arn:aws:iam::11111111111:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/${oidc}"]
federatedList2 = join("", [for oidc in local.federated : "\"oidc.eks.us-east-1.amazonaws.com/id/${oidc}:sub:\", \"system:serviceaccount:%s:%s\""])eks_assume_policy.json.tpl
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "${federatedList1}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"${federatedList2}"
}
}
}
]
}IAM角色
resource "aws_iam_role" "route53_role" {
name = "xxxxx"
assume_role_policy = format(templatefile("./eks_assume_policy.json.tpl", {
federatedList1 = [for oidc in local.federated : "arn:aws:iam::1111111111:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/${oidc}"]
federatedList2 = join("", [for oidc in local.federated : "\"oidc.eks.us-east-1.amazonaws.com/id/${oidc}:sub:\", \"system:serviceaccount:%s:%s\""])
}), "namespace", local.name)
tags = {
terraform = "true"
owner = "test"
}
}错误:函数调用中出错
on main.tf line 49, in resource "aws_iam_role" "route_53_role":
49: assume_role_policy = format(templatefile("./eks_assume_policy.json.tpl", {
50:
51:
52:
|----------------
| local.federated is tuple with 2 elements
Call to function "templatefile" failed: ./eks_assume_policy.json.tpl:7,25-39:
Invalid template interpolation value; Cannot include the given value in a
string template: string required..Update1:
我正在尝试使用eks_assume_policy.json.tpl访问这两个群集
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": [
"arn:aws:iam::111111111:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/xxxxxxxxxxxx",
"arn:aws:iam::111111111:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/yyyyyyyyyyy"
]
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.us-east-1.amazonaws.com/id/xxxxxxxxxxxx:sub": "system:serviceaccount:%s:%s",
"oidc.eks.us-east-1.amazonaws.com/id/yyyyyyyyy:sub": "system:serviceaccount:%s:%s"
}
}
}
]
}发布于 2020-12-18 14:51:50
通常,一种用于解决此问题的模式是通过jsonencode。在这种情况下,模板文件为:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": ${jsonencode(federatedList1)}
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals":
${jsonencode(federatedList2)}
}
}
]
}federatedList1现在应该是正确的。我不确定您试图用federatedList2实现什么,因此对federatedList2的修改可能需要更多的修改。
发布于 2020-12-19 09:01:01
The templatefile documentation中有一节专门介绍了这种情况,标题为Generating JSON or YAML from a template,开头是这样说的:
如果您想要生成的字符串将采用JSON或YAML语法,那么编写一个模板来生成有效的JSON或YAML模板通常是非常棘手和乏味的,当使用大量单独的插值序列和指令时,这些模板将被正确解释。
相反,您可以编写一个模板,该模板只包含对jsonencode或yamlencode的单个插值调用,并使用常规Terraform表达式语法指定要编码的值。
然后,文档给出了模板的一些简单示例,该模板的整个内容都是对jsonencode或yamldecode的调用,但是由于您在这里给出了一个特定的模板作为示例,因此我可以展示将模板转换为文档建议的形式的结果:
${jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Federated = federatedList1
}
Action = "sts:AssumeRoleWithWebIdentity"
Condition = {
StringEquals = federatedList2
}
},
]
})}请注意,在本例中,整个模板是一个单独的interpolation sequence ${ ... },其结果将是作为参数提供给jsonencode的Terraform表达式的JSON等效项。这意味着您可以使用所有普通的Terraform language expression features,包括直接引用从主配置传入的值,Terraform会自动将结果转换为合适的JSON语法。
在本例中,因为federatedList1和federatedList2都是由for表达式产生的元组,所以结果将是the jsonencode function's documentation中显示的每个类型映射表的JSON数组。
https://stackoverflow.com/questions/65351694
复制相似问题