我有一个用例,我想创建2个应用程序负载平衡器,其中一个将是公共的,另一个将使用terraform模块是私有的。
我知道我们可以使用相同类型的代码分别为私有和公共参数创建2个目录,但是我试图通过使用terraform插值来创建两个负载均衡器,如下所述。
ALB模块:
resource "aws_alb" "default" {
name = "${var.name}-${var.env_name}-${var.internal == "false" ? "public" : "private" }"
internal = "${var.internal == "false" ? "false" : "true" }"
security_groups = ["${var.internal == "false" ? var.sg80 : var.instance_in_all }"]
subnets = ["${var.internal == "false" ? var.public_subnets : var.private_subnets }"]
}
main.tf ,我从那里调用alb模块。
module "public-alb" {
source = "../../modules/alb"
name = "example"
internal = "false" #internal: Give it false for public load balancer.
env_name = "production"
vpc_id = "${module.vpc.vpc_id}"
public_subnets = "${module.vpc.public_subnets}"
private_subnets = "${module.vpc.public_subnets}" #This does not matter here because check condition in internal file.
sg80 = "${module.security-group.sg80}"
instance_in_all = "${module.security-group.instance_in_all}" #This does not matter here because check condition in internal file.
}
module "private-alb" {
source = "../../modules/alb"
name = "example"
internal = "true" #internal: Give it false for public load balancer.
env_name = "production"
vpc_id = "${module.vpc.vpc_id}"
private_subnets = "${module.vpc.public_subnets}"
public_subnets = "${module.vpc.public_subnets}" #This does not matter here because check condition in internal file.
sg80 = "${module.security-group.sg80}" #This does not matter here because check condition in internal file.
instance_in_all = "${module.security-group.instance_in_all}"
}
因此,对于公共负载平衡器,我必须传递与私有负载平衡器相同的私有子网和内部安全组,因为我要从variables.tf(下面提到)传递这些变量,所以我必须传递公共子网和外部安全组。没必要。
variable "vpc_id" {}
#variable "private_subnets" { type = "list"}
variable "sg80" {}
variable "public_subnets" {
type = "list"
}
variable "name" {}
variable "internal" {}
variable "env_name" {}
variable "private_subnets" {
type = "list"
}
variable "instance_in_all" {}
我想知道这是正确的方法,还是目前唯一的解决方法是单独的目录。
答案 0 :(得分:1)
几种可能的情况:
1)最高可配置性:我不会公开公开和私有使用所需的两个变量。仅一个变量称为“子网”,并从模块外部为变量分配一个值。另外,当同时传递private_subnets和public_subnets时,如果要在仅包含公共负载均衡器的环境中使用该模块,则必须以某种方式解决传递私有子网和安全组的问题,从而妨碍了可重用性。
2)减少样板,这就是我解释您的问题的方式:在模块内部使用数据源。如果您希望完全自治(例如,仅通过internal = true / false),并且具有针对这些方案的固定子网和安全组,则可以使用数据源获取它们,其中查询取决于var.internal是true还是false。
示例:
data "aws_security_groups" "private_lb" {
tags {
SomeTag = "something_that_accurately selects my private security groups"
}
}
data "aws_security_groups" "public_lb" {
tags {
SomeTag = "something_that_accurately selects my public security groups"
}
}
resource "aws_alb" "default" {
name = "${var.name}-${var.env_name}-${var.internal == "false" ? "public" : "private" }"
internal = "${var.internal == "false" ? "false" : "true" }"
security_groups = ["${var.internal == "false" ? data.aws_security_groups.public_lb.ids : data.aws_security_groups.private_lb.ids }"]
etc...
}
当然,您也可以将条件部分放在数据源本身中,例如更改基于var.internal的过滤器。
第三个选择是在模块内部创建一个专用的安全组,并基于var.internal分配默认的入口/出口规则,在output
中公开该组的ID,以便您可以添加其他从模块外部对其进行控制。