Arv*_*vin 11 terraform hcl terraform-provider-aws terraform0.12+
我正在实现一个安全组模块,以便它将通过获取和过滤 cidr 和 source_security_group_id 创建安全组规则来创建安全组规则。
当前模块配置。
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
}
Run Code Online (Sandbox Code Playgroud)
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" }
]
}
Run Code Online (Sandbox Code Playgroud)
因此,这里的问题陈述是当我使用上面的映射列表调用模块中的安全组规则时,它应该检查它是 source_sg_id 还是 cidr。
然后过滤这些映射并将其传递给模块中的相应资源。
前任:
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" }
]
}
Run Code Online (Sandbox Code Playgroud)
应查找这些规则并将第一个规则传递给 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
....
}
Run Code Online (Sandbox Code Playgroud)
所以,我正在寻找一种根据键从列表中过滤地图的方法
我尝试过查找,但对于字符串列表没有帮助。
我想出了一个聪明的方法来做到这一点。
假设我试图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"
}
]
}
Run Code Online (Sandbox Code Playgroud)
pets_map首先使用索引tostring(i)作为键将宠物列表转换为宠物地图。这将在步骤 3 中用于查找过滤后的宠物。locals {
pets_map = { for i, pet in var.pets : tostring(i) => pet }
}
Run Code Online (Sandbox Code Playgroud)
pet.kind == "cat"
字符串,创建分别与条件匹配的键的过滤列表。pets_map然后压缩列表,从列表中删除空字符串。locals {
cats_keys = compact([for i, pet in local.pets_map : pet.kind == "cat" ? i : ""])
}
Run Code Online (Sandbox Code Playgroud)
cats_keys并从 中查找相应的宠物pets_map。现在您已过滤出猫类宠物列表kind = "cat"。locals {
cats = [for key in local.cats_keys : lookup(local.pets_map, key)]
}
Run Code Online (Sandbox Code Playgroud)
您现在可以使用 访问猫local.cats,这将为您提供以下地图。
{
name = "Milo"
kind = "cat"
},
{
name = "Simba"
kind = "cat"
}
Run Code Online (Sandbox Code Playgroud)
下面是完整的示例。
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)]
}
Run Code Online (Sandbox Code Playgroud)
考虑创建另一个模块来处理规则,并在该模块内设置安全组资源。
module "security_groups" {
count = length(var.security_group_rules)
source_sg_id_rule = var.security_group_rules[count.index].source_sg_id_rule
}
Run Code Online (Sandbox Code Playgroud)
然后,在新模块中,使用 count 语句作为测试来创建可选项目:
resource "aws_security_group_rule" "source_sg_id_rule" {
count = length(var.source_sg_id_rule) == 0 ? 0 : 1
type = var.type
from_port = var.from_port
to_port = var.to_port
protocol = var.protocol
source_security_group_id = var.source_security_group_id
description = var.description
security_group_id = var.security_group_id
}
Run Code Online (Sandbox Code Playgroud)
这会将资源创建为由一个或零个项目组成的数组,并删除任何为零的列表。
| 归档时间: |
|
| 查看次数: |
23598 次 |
| 最近记录: |