使用Terraform使用多个IAM策略创建多个IAM组

时间:2020-07-22 08:29:44

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

我尝试创建多个IAM组,然后使用terraform(v0.12)将多个AWS策略附加到每个组。

目前,我有:

resource "aws_iam_group" "group1" {
  name = "group1"
  path = "/"
}

resource "aws_iam_group" "group2" {
  name = "group2"
  path = "/"
}

resource "aws_iam_group_policy_attachment" "group1" {
  for_each = toset([
    "arn:aws:iam::aws:policy/AmazonS3FullAccess",
    "arn:aws:iam::aws:policy/AmazonCodeGuruProfilerFullAccess",
    "arn:aws:iam::aws:policy/job-function/Billing"
  ])
  group      = aws_iam_group.group1.name
  policy_arn = each.value
}

有没有一种更干净的方法可以完成此操作,这样我就不会最终使用太多重复的代码。

1 个答案:

答案 0 :(得分:0)

您可以使用内置的setproduct函数来实现此功能。

例如,给定以下Terraform配置:

variable "group_names" {
  default = []
  type    = set(string)
}

variable "policy_arns" {
  default = []
  type    = set(string)
}

locals {
  group_policies = [
    for group_policy in setproduct(var.group_names, var.policy_arns) : {
      group_name = group_policy[0]
      policy_arn = group_policy[1]
    }
  ]
}

resource "aws_iam_group" "iam_group" {
  for_each = var.group_names

  name = each.value
}

resource "aws_iam_group_policy_attachment" "iam_group_policy_attachment" {
  for_each = {
    for group_policy in local.group_policies : "${group_policy.group_name}.${group_policy.policy_arn}" => group_policy
  }

  group      = each.value.group_name
  policy_arn = each.value.policy_arn
}

得出以下计划:

Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.


------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_iam_group.iam_group["group1"] will be created
  + resource "aws_iam_group" "iam_group" {
      + arn       = (known after apply)
      + id        = (known after apply)
      + name      = "group1"
      + path      = "/"
      + unique_id = (known after apply)
    }

  # aws_iam_group.iam_group["group2"] will be created
  + resource "aws_iam_group" "iam_group" {
      + arn       = (known after apply)
      + id        = (known after apply)
      + name      = "group2"
      + path      = "/"
      + unique_id = (known after apply)
    }

  # aws_iam_group_policy_attachment.iam_group_policy_attachment["group1.arn:aws:iam::aws:policy/AmazonCodeGuruProfilerFullAccess"] will be created
  + resource "aws_iam_group_policy_attachment" "iam_group_policy_attachment" {
      + group      = "group1"
      + id         = (known after apply)
      + policy_arn = "arn:aws:iam::aws:policy/AmazonCodeGuruProfilerFullAccess"
    }

  # aws_iam_group_policy_attachment.iam_group_policy_attachment["group1.arn:aws:iam::aws:policy/AmazonEC2FullAccess"] will be created
  + resource "aws_iam_group_policy_attachment" "iam_group_policy_attachment" {
      + group      = "group1"
      + id         = (known after apply)
      + policy_arn = "arn:aws:iam::aws:policy/AmazonEC2FullAccess"
    }

  # aws_iam_group_policy_attachment.iam_group_policy_attachment["group1.arn:aws:iam::aws:policy/AmazonS3FullAccess"] will be created
  + resource "aws_iam_group_policy_attachment" "iam_group_policy_attachment" {
      + group      = "group1"
      + id         = (known after apply)
      + policy_arn = "arn:aws:iam::aws:policy/AmazonS3FullAccess"
    }

  # aws_iam_group_policy_attachment.iam_group_policy_attachment["group2.arn:aws:iam::aws:policy/AmazonCodeGuruProfilerFullAccess"] will be created
  + resource "aws_iam_group_policy_attachment" "iam_group_policy_attachment" {
      + group      = "group2"
      + id         = (known after apply)
      + policy_arn = "arn:aws:iam::aws:policy/AmazonCodeGuruProfilerFullAccess"
    }

  # aws_iam_group_policy_attachment.iam_group_policy_attachment["group2.arn:aws:iam::aws:policy/AmazonEC2FullAccess"] will be created
  + resource "aws_iam_group_policy_attachment" "iam_group_policy_attachment" {
      + group      = "group2"
      + id         = (known after apply)
      + policy_arn = "arn:aws:iam::aws:policy/AmazonEC2FullAccess"
    }

  # aws_iam_group_policy_attachment.iam_group_policy_attachment["group2.arn:aws:iam::aws:policy/AmazonS3FullAccess"] will be created
  + resource "aws_iam_group_policy_attachment" "iam_group_policy_attachment" {
      + group      = "group2"
      + id         = (known after apply)
      + policy_arn = "arn:aws:iam::aws:policy/AmazonS3FullAccess"
    }

Plan: 8 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

setproduct函数返回给定2个或更多参数的元素的所有可能组合。

for_each中的aws_iam_group_policy_attachment表达式创建了一个键值对映射,其中每个键的格式都像group_name.policy_arn(例如"group2.arn:aws:iam::aws:policy/AmazonS3FullAccess"),每个值是分别包含两个键group_namepolicy_arn的地图。

for_each表达式中创建唯一键很重要,以防止覆盖地图中现有键的可能性。

相关问题