我该怎么做才能在我想要的时候不附加政策

How can I do so that policies are not attached when I want

我有一个问题,我需要创建组并为这些组附加策略,但我还需要,如果变量 policy_name 等于“”,他根本不相信我,我知道是重复的,但我被要求这样做我感谢你的支持

这是我的main.tf

resource "aws_iam_group" "this" {
 count = length(var.name) != 0 ? length(var.name) : 0
 
 name = element(var.name, count.index)
 path = var.path
}
 
resource "aws_iam_policy" "prueba" {
 count = var.policy_name != "" ? 1 : 0
 
 name = var.policy_name
 policy = jsonencode(var.policy)
}
 
resource "aws_iam_group_policy_attachment" "test-attach" {
 for_each = toset(var.name)
 group = each.key
 policy_arn = aws_iam_policy.prueba[0].arn
}

This is variables

variable "name" {
 description = "Name of IAM group"
 type = list
 default = []
}
  
variable "policy" {
 description = "The policy in IAM (tpl file)"
 type = any
 default = null
}
 
variable "policy_name" {
 type = string
 default = ""
}

This is de var.tfvars

policy = {
 "Version": "2012-10-17",
 "Statement": [
 {
 "Action": [
 "autoscaling:Describe*",
 "cloudwatch:*",
 "logs:*",
 "sns:*",
 "iam:GetPolicy",
 "iam:GetPolicyVersion",
 "iam:GetRole"
 ],
 "Effect": "Allow",
 "Resource": "*"
 },
 {
 "Effect": "Allow",
 "Action": "iam:CreateServiceLinkedRole",
 "Resource": "arn:aws:iam:::role/aws-service-role/events.amazonaws.com/AWSServiceRoleForCloudWatchEvents",
 "Condition": {
 "StringLike": {
 "iam:AWSServiceName": "events.amazonaws.com"
 }
 }
 },
 {
 "Action": [
 "cloudwatch:DeleteAlarms",
 "cloudwatch:DeleteAnomalyDetector",
 "cloudwatch:DeleteDashboards",
 "cloudwatch:DeleteInsightRules",
 "cloudwatch:DeleteMetricStream"
 ],
 "Effect": "Deny",
 "Resource": "*"
 },
 {
 "Action": [
 "logs:DeleteDestination",
 "logs:DeleteLogDelivery",
 "logs:DeleteLogGroup",
 "logs:DeleteLogStream",
 "logs:DeleteMetricFilter",
 "logs:DeleteQueryDefinition",
 "logs:DeleteResourcePolicy",
 "logs:DeleteRetentionPolicy",
 "logs:DeleteSubscriptionFilter"
 ],
 "Effect": "Deny",
 "Resource": "*"
 },
 {
 "Action": [
 "sns:DeleteEndpoint",
 "sns:DeletePlatformApplication",
 "sns:DeleteSMSSandboxPhoneNumber",
 "sns:DeleteTopic",
 "sns:RemovePermission"
 ],
 "Effect": "Deny",
 "Resource": "*"
 },
 {
 "Action": "events:*",
 "Effect": "Allow",
 "Resource": "*"
 },
 {
 "Action": [
 "events:RemovePermission",
 "events:DeleteApiDestination",
 "events:DeleteRule",
 "events:DeleteArchive",
 "events:DeleteConnection",
 "events:DeletePartnerEventSource",
 "events:DeleteEventBus"
 ],
 "Effect": "Deny",
 "Resource": "*"
 }
 ]
}

name = ["test_group","test_group_1","test_group_2"]
policy_name = ""

这是错误

 Error: Invalid index
    
           on ../groups/main.tf line 18, in resource "aws_iam_group_policy_attachment" 
"test-attach":
           18:   policy_arn = aws_iam_policy.prueba[0].arn
             ├────────────────
             │ aws_iam_policy.prueba is empty tuple
        
         The given key does not identify an element in this collection value.

如果您有一个仅在某些情况下定义的对象,那么您必须向 Terraform 解释模块的其他部分应该如何对该对象不存在做出反应。

在您的情况下,您有一个 IAM 策略,该策略可能存在也可能不存在,具体取决于条件 var.policy_name != "" ? 1 : 0。但是,您有另一个资源,它只有在策略存在时才能存在,因此 Terraform 正确地返回了一个错误,说明您无法引用不存在的策略的 ARN。

由于 aws_iam_group_policy_attachment 的含义是在 IAM 组和 IAM 策略之间创建关系,您可能需要为每对组和策略创建该资源类型的实例。表示这种关系的典型方法是使用 the setproduct function,它计算一组其他两个集合中元素的所有组合。

例如:

resource "aws_iam_group_policy_attachment" "test-attach" {
 for_each = {
   for pair in setproduct(toset(var.name), toset(aws_iam_policy.prueba)) :
   "${pair[0]}:${pair[1].name}" => {
     group_name = pair[0]
     policy_arn = pair[1].arn
   }
 }

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

for_each 表达式的组成部分比您开始时的要多得多,因此我将尝试总结每个部分的作用:

  • { for ... in ... : ... => ...} 部分是 for expression,它允许从另一个集合值派生一个集合值。在这种情况下,源集合是 setproduct 结果。
  • setproduct(...) 采用一个或多个设置值,returns 一组新的元组表示给定集合中元素的所有组合。在这种情况下,它 returns 一组 [ group_name, policy_object ] 对,其中 group_name 是来自 var.name 的元素之一, policy_object 是表示其中一个的对象aws_iam_policy.prueba.
  • 实例
  • for_each 需要为指定为映射键的每个实例指定一个唯一键,因此 for 表达式将该组元组转换为一个映射,其中键是通过组合一组来构建的名称和策略名称,每个值都是一个对象,描述一个相关的组名称和一个相关的策略 ARN。
  • 由于该资源块中的 each.value 始终引用该结果映射中的值之一,我们可以引用 each.value.group_nameeach.value.policy_arn 来填充那些特定的配对单个实例。

请注意 setproduct 始终 returns 一个集合,其元素数是给定集合中元素数的乘积,因此如果其中任何一个元素为零,则结果将为零元素——零乘以任何值都是零。这最终避免了您在这里遇到的问题,因为如果您有零组 零策略,那么您将有零附件。