我正在实现一个安全组模块,这样它将通过过滤 cidr 和 source_security_group_id 创建安全组规则来创建安全组规则。
当前模块配置。
安全组模块.tf
resource "aws_security_group" "this" {
name = var.name
description = var.description
vpc_id = var.vpc_id
revoke_rules_on_delete = var.revoke_rules_on_delete
}
## CIDR Rule
resource "aws_security_group_rule" "cidr_rule" {
count = length(var.security_group_rules)
type = var.security_group_rules[count.index].type
from_port = var.security_group_rules[count.index].from_port
to_port = var.security_group_rules[count.index].to_port
protocol = var.security_group_rules[count.index].protocol
cidr_blocks = var.security_group_rules[count.index].cidr_block
description = var.security_group_rules[count.index].description
security_group_id = aws_security_group.this.id
}
## Source_security_group_id Rule
resource "aws_security_group_rule" "source_sg_id_rule" {
count = length(var.security_group_rules)
type = var.security_group_rules[count.index].type
from_port = var.security_group_rules[count.index].from_port
to_port = var.security_group_rules[count.index].to_port
protocol = var.security_group_rules[count.index].protocol
source_security_group_id = var.security_group_rules[count.index].source_security_group_id
description = var.security_group_rules[count.index].description
security_group_id = aws_security_group.this.id
}
主文件module "sample_sg" {
source = "./modules/aws_security_group"
name = "test-sg"
vpc_id = "vpc-xxxxxx"
security_group_rules = [
{ type = "ingress", from_port = 22, to_port = 22, protocol = "tcp", cidr_block = [var.vpc_cidr], description = "ssh" },
{ type = "ingress", from_port = 80, to_port = 80, protocol = "tcp", cidr_block = [var.vpc_cidr], description = "http" },
{ type = "ingress", from_port = 0, to_port = 0, protocol = "-1", source_sg_id = "sg-xxxx", description = "allow all" }
{ type = "egress", from_port = 0, to_port = 0, protocol = "-1", source_sg_id = "sg-xxxx", description = "allow all" }
]
}
所以,这里的问题陈述是当我用上面的映射列表调用模块中的安全组规则时,它应该检查它是source_sg_id还是cidr。然后过滤这些 map 并将其传递给模块中的相应资源。
前任:
module ""{
...
security_group_rules = [
{ type = "ingress", from_port = 22, to_port = 22, protocol = "tcp", cidr_block = [var.vpc_cidr], description = "ssh" },
{ type = "ingress", from_port = 0, to_port = 65535, protocol = "-1", source_sg_id = "sg-xxxx", description = "allow all" }
]
}
应该查找这些规则并将第一个规则传递给 CIDR 规则,将第二个规则传递给 Source_security_group_id 规则。我正在考虑使它如下
locals {
sid_rules = some_function{var.security_group_rules, "source_security_group_id"}
cidr_rules = some_function{var.security_group_rules, "cidr"}
}
resource "aws_security_group_rule" "cidr_rule" {
count = count(local.cidr_rules)
....
cidr_blocks = local.cidr_rules[count.index].cidr_block
....
}
resource "aws_security_group_rule" "sid_rule" {
count = count(local.sid_rules)
....
source_security_group_id = local.sid_rules[count.index].source_sg_id
....
}
所以,我正在寻找一种方法来根据 从列表中过滤 map 。关键 我尝试过查找,但在字符串列表的情况下没有帮助。
最佳答案
我想出了一个聪明的方法来做到这一点。
假设我试图只过滤猫的宠物kind = "cat"
从宠物列表中。
variable "pets" {
type = list(object({
name = string
kind = string
}))
default = [
{
name = "Fido"
kind = "dog"
},
{
name = "Max"
kind = "dog"
},
{
name = "Milo"
kind = "cat"
},
{
name = "Simba"
kind = "cat"
}
]
}
pets_map
使用索引 tostring(i)
的宠物作为关键。这将在第 3 步中用于查找过滤后的宠物。
locals {
pets_map = { for i, pet in var.pets : tostring(i) => pet }
}
pet.kind == "cat"
的键的过滤列表通过循环
pets_map
中的键并将不匹配的相应键设置为空字符串。然后压缩从列表中删除空字符串的列表。
locals {
cats_keys = compact([for i, pet in local.pets_map : pet.kind == "cat" ? i : ""])
}
cats_keys
并从 pets_map
中查找相应的宠物.现在轮到你有猫的过滤列表
kind = "cat"
. locals {
cats = [for key in local.cats_keys : lookup(local.pets_map, key)]
}
您现在可以使用 local.cats
访问猫,这将为您提供以下 map 。{
name = "Milo"
kind = "cat"
},
{
name = "Simba"
kind = "cat"
}
下面是完整的例子。variable "pets" {
type = list(object({
name = string
kind = string
}))
default = [
{
name = "Fido"
kind = "dog"
},
{
name = "Max"
kind = "dog"
},
{
name = "Milo"
kind = "cat"
},
{
name = "Simba"
kind = "cat"
}
]
}
locals {
pets_map = { for i, pet in var.pets : tostring(i) => pet }
cats_keys = compact([for i, pet in local.pets_map : pet.kind == "cat" ? i : ""])
cats = [for key in local.cats_keys : lookup(local.pets_map, key)]
}
关于terraform:根据键过滤 map 列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65956626/