【问题标题】:Conditionally set IAM policy based on whether a certain resource exists or not in Terraform根据 Terraform 中是否存在某个资源,有条件地设置 IAM 策略
【发布时间】:2021-04-06 16:34:58
【问题描述】:

我正在尝试根据 IAM 角色是否存在来设置 KMS 密钥策略。 yaml 文件如下所示。

data "aws_iam_policy_document" "key_policy" {
  statement {
    sid = "Give Access to the my Role"

    actions = [
      "kms:GenerateDateKey",
      "kms:Decrypt"
    ]

    resources = ["*"]

    principals {
      type        = "AWS"
      identifiers = ["arn:aws:iam::${var.account_id}:role/myrole"]
    }
  }
}

这个 terraform 脚本的问题是,如果我的帐户中不存在 myrole,它将失败。我们有多个 AWS 账户,其中只有一部分有这个myrole。我们的 CI 将为所有帐户运行相同的脚本。有没有办法仅在myrole 存在时应用此语句?

【问题讨论】:

  • myrole 是由 terraform 管理,还是完全独立于您在每个帐户中使用的 terraform 配置?
  • 感谢@Marcin 的评论。它由一组不同的 terraform 脚本管理。这些脚本在不同的 CI 下单独运行。话虽如此,我不确定是否可以在这两组脚本之间共享存在状态。

标签: amazon-web-services terraform amazon-iam amazon-kms


【解决方案1】:

terraform (TF) 的设计原则规定当前的 TF 配置文件应明确定义您的基础架构。这意味着定义您的解决方案的资源仅由给定的配置文件和当前的 TF 状态管理。如果某些资源不处于 TF 状态,则认为它超出了 TF 的范围,不存在。

因此,TF 不直接支持检查任何资源的存在性,也不支持基于此类条件的conditional creation of resources。这会导致问题,因为您的 TF 不能完全代表您的架构。

为此,TF docs推荐:

我们建议应用依赖倒置方法:让模块接受它需要的对象作为参数,而不是尝试编写一个自身尝试检测是否存在并创建它的模块,通过输入变量

基于上述,您应该致力于开发您的aws_iam_policy_document.key_policy,以便它基于输入变量创建有问题的statement。这意味着您的 CICD 管道必须检查角色的存在并将此信息作为输入变量传递到您的 CF 文件,例如my_role_existstruefalse 值。

然后,您可以使用dynamic blocks 使statement 成为条件:

data "aws_iam_policy_document" "key_policy" {

  dynamic "statement" {

    for_each = var.my_role_exists == true ? [1] : [] 

    content {
      sid = "Give Access to the my Role"

      actions = [
        "kms:GenerateDateKey",
        "kms:Decrypt"
      ]

      resources = ["*"]

      principals {
        type        = "AWS"
        identifiers = ["arn:aws:iam::${var.account_id}:role/myrole"]
      }
    }
   } 
}

【讨论】:

    猜你喜欢
    • 2021-08-28
    • 2021-03-06
    • 2020-11-09
    • 2020-09-04
    • 1970-01-01
    • 1970-01-01
    • 2017-12-09
    • 2021-01-12
    • 2020-07-21
    相关资源
    最近更新 更多