Terraform:使用带插值模块的公共和私有应用程序负载均衡器

时间:2018-12-02 16:32:40

标签: terraform terraform-provider-aws aws-alb

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

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

1 个答案:

答案 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,以便您可以添加其他从模块外部对其进行控制。