1

我有一个用例,我想创建 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}" 
    }

因此,对于公共负载均衡器,我必须传递与私有负载均衡器相同的私有子网和内部安全组.

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" {}

我想知道这是正确的方法还是单独的目录是目前唯一的解决方法。

4

1 回答 1

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 分配默认的入口/出口规则,在您的模块中公开该组的 ID,output以便您可以从模块外部向其添加其他规则。

于 2018-12-03T14:05:17.433 回答