首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在terraform中传递tpl文件的复杂变量?

如何在terraform中传递tpl文件的复杂变量?
EN

Stack Overflow用户
提问于 2020-12-18 12:10:30
回答 2查看 807关注 0票数 0

我正在尝试创建一个tpl文件。因此我可以为我角色提供访问多个k8s群集的权限。但是我得到了一个元组错误。

当tpl文件有一些插值时,我们应该如何将变量传递给tpl文件?也请让我知道这个错误是什么意思,以及我哪里错了。

Terraform版本: 0.12.28

locals.tf

代码语言:javascript
复制
 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

代码语言:javascript
复制
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "${federatedList1}"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "${federatedList2}"
        }
      }
    }
  ]
}

IAM角色

代码语言:javascript
复制
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"
  }
}

错误:函数调用中出错

代码语言:javascript
复制
 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访问这两个群集

代码语言:javascript
复制
{
  "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"
        }
      }
    }
  ]
}
EN

回答 2

Stack Overflow用户

发布于 2020-12-18 14:51:50

通常,一种用于解决此问题的模式是通过jsonencode。在这种情况下,模板文件为:

代码语言:javascript
复制
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": ${jsonencode(federatedList1)}
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": 
          ${jsonencode(federatedList2)}
      }
    }
  ]
}

federatedList1现在应该是正确的。我不确定您试图用federatedList2实现什么,因此对federatedList2的修改可能需要更多的修改。

票数 2
EN

Stack Overflow用户

发布于 2020-12-19 09:01:01

The templatefile documentation中有一节专门介绍了这种情况,标题为Generating JSON or YAML from a template,开头是这样说的:

如果您想要生成的字符串将采用JSON或YAML语法,那么编写一个模板来生成有效的JSON或YAML模板通常是非常棘手和乏味的,当使用大量单独的插值序列和指令时,这些模板将被正确解释。

相反,您可以编写一个模板,该模板只包含对jsonencodeyamlencode的单个插值调用,并使用常规Terraform表达式语法指定要编码的值。

然后,文档给出了模板的一些简单示例,该模板的整个内容都是对jsonencodeyamldecode的调用,但是由于您在这里给出了一个特定的模板作为示例,因此我可以展示将模板转换为文档建议的形式的结果:

代码语言:javascript
复制
${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语法。

在本例中,因为federatedList1federatedList2都是由for表达式产生的元组,所以结果将是the jsonencode function's documentation中显示的每个类型映射表的JSON数组。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65351694

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档