我怎样做才能在我想要的时候不附加策略



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

This is my 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策略之间创建关系,因此您可能需要为每一对组和策略创建该资源类型的实例。表示这种关系的典型方法是使用setproduct函数,该函数计算其他两个集合中所有元素的组合的集合。

例如:

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表达式,允许从一个集合值派生另一个集合值。在本例中,源集合是setproduct结果。
  • setproduct(...)接受一个或多个集合值,并返回一个新的元组集合,表示给定集合中所有元素的组合。在这种情况下,它返回一组[ group_name, policy_object ]对,其中group_namevar.name中的一个元素,policy_object是代表aws_iam_policy.prueba实例之一的对象。
  • for_each要求为每个实例指定一个唯一的键作为映射键,因此for表达式将该元组集合转换为映射,其中键是通过组合组名和策略名称构建的,并且每个值都是描述一个相关组名和一个相关策略ARN的对象。
  • 由于资源块中的each.value总是引用结果映射中的一个值,我们可以引用each.value.group_nameeach.value.policy_arn来填充单个实例的特定配对。

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

最新更新