我正在使用 terraform 进行概念验证工作,以将我们的基础架构代码移至其中。这是我的第二天,我觉得我在尝试设置网络 ACL 时做错了什么或遗漏了一些要点,因为代码很快变得非常复杂,甚至没有解决所有重复问题。
我尝试创建一个可以在整个环境中重复使用的 network-acl-rule 模块。目前它看起来像这样;
# modules/acl/main.tf
resource "aws_network_acl_rule" "acl-rule-example" {
network_acl_id = "${var.network_acl_id}"
count = "${length(var.cidrs) * length(var.rules)}"
rule_number = "${var.rule_number + count.index}"
from_port = "${element(var.all_acl_rules[var.rules[floor(count.index / length(var.cidrs))]], 0)}"
to_port = "${element(var.all_acl_rules[var.rules[floor(count.index / length(var.cidrs))]], 1)}"
egress = "${element(var.all_acl_rules[var.rules[floor(count.index / length(var.cidrs))]], 2)}"
protocol = "${element(var.all_acl_rules[var.rules[floor(count.index / length(var.cidrs))]], 3)}"
rule_action = "${element(var.all_acl_rules[var.rules[floor(count.index / length(var.cidrs))]], 4)}"
cidr_block = "${element(var.cidrs, count.index)}"
}
我将它与以下变量和模块声明一起使用,以使您更容易理解。
# variables.tf
variable "all_acl_rules" {
type = "map"
# [from_port, to_port, egress, protocol, action, description]
default = {
# ephemeral outbound
ephemeral_outbound = [1024, 65535, true, "tcp", "allow", "ephemeral-outbound"]
# basic inbounds
http_inbound = [80, 80, false, "tcp", "allow", "http-inbound"]
https_inbound = [443, 443, false, "tcp", "allow", "https-inbound"]
ssh_inbound = [22, 22, false, "tcp", "allow", "https-inbound"]
# :::
}
}
variable "cidr_blocks" {
type = "map"
default = {
"all" = ["0.0.0.0/0"],
"vpc" = ["10.0.0.0/8"],
"clients" = ["x.x.x.x/32", "x.x.x.x/32", "x.x.x.x/30"],
# :::
}
}
下面是我如何调用模块
# main.tf
module "clients-acl-rule" {
source = "modules/acl"
network_acl_id = "${aws_network_acl.public-acl.id}"
all_acl_rules = "${var.acl_rules}"
cidrs = "${var.cidr_blocks["clients"]}"
rules = ["http_inbound", "https_inbound", "ephemeral_outbound"]
rule_number = 20
}
我可以有一个臃肿的模块实现,因为这将被编写一次,并且永远不会再回头看网络 acl 之类的东西。此实现非常适合按某些 cidr 块对规则进行分组。但它的缺点是我需要为每个不同的 cidr 块重复调用模块多次,我需要会产生大量重复的规则。
最后,我想要实现的是,拥有一个模块,我可以说这个 cidr 块的 http_inbound、这个 cidr 块的 ssh 入站和所有 vpc 类型的灵活性的临时出站。
我可以争取更多地膨胀模块代码,但我觉得这不是做 ACL 的正确方法。也许更聪明的变量定义有更多的重复而不是调用模块时的重复。人们如何用 terraform 解决这类问题?