如何有条件地合并Terraform中的多个IAM政策声明?

人气:879 发布:2022-10-16 标签: amazon-web-services terraform amazon-iam

问题描述

我正在尝试使用Terraform 0.13编写一个内部模块,它允许调用者在调用时选择一个或多个预写的策略文档。我想要做的是将每个策略定义为一个data.iam_策略_文档,并有条件地将它们作为多个语句包含/合并到结果策略中。我找到的示例似乎都不能很好地做到这一点,注册表中的大多数IAM相关模块只是依赖于传递完整策略声明的父模块,但我的目标是让模块的用户不需要了解如何编写正确的IAM策略。

我认为最简单的方法是合并策略文档的.json版本并将其传递给IAM_POLICY资源,但这似乎不适合通过计数三元组控制策略文档,我意识到这可能是完全错误的方法。

使用该模块的预期结果是创建具有适当信任策略的单个角色,该角色可以访问所选的服务组,并且不会创建任何未使用和未生成种子的资源(保持未附加状态的额外策略等)

推荐答案

aws_iam_policy_document主要用于定义全新的策略,但对于这种争论现有策略的任务(我认为它可能是也可能不是用aws_iam_policy_document创建的),我认为使用jsondecode解码策略JSON,然后在重新合并结果之前使用这些生成的数据结构会更容易。

如果策略可能相互依赖或相互冲突,情况可能会变得复杂,但如果您可以假设所有策略都将彼此独立,那么您可能只需将每个文档中的Statement数组串联在一起。

例如:

variable "iam_policies_json" {
  type = list(string)
}

locals {
  iam_policies = [for src in var.iam_policies_json : jsondecode(src)]
  iam_policy_statements = flatten([
    for policy in local.iam_policies : policy.Statement
  ])
  merged_policy = jsonencode({
    Version   = "2012-10-17"
    Statement = local.iam_policy_statements
  })
}

上面只是无条件地将它们全部合并在一起,但是一旦您拥有了像这里的local.iam_policy_statements这样的数据结构,您就可以潜在地使用其他Terraform表达式构造,例如带有if子句的for表达式,来有条件地筛选出您不想包括在结果中的任何策略。

524