簡體   English   中英

使用 for each 創建多個目標組和聽眾

[英]Create multiple target groups and listeners using for each

我正在嘗試使用 For Each 在 Terraform 中創建多個應用程序目標組和偵聽器。 我有一些復雜的設置來處理偵聽器規則,以根據 HTTP 標頭將流量路由到目標組。 下面是我寫的資源:

resource "aws_lb_listener" "app_listener_forward" {
  for_each          = var.listeners
  load_balancer_arn = aws_lb.app_alb.arn
  port              = each.value.listeners
  protocol          = "HTTPS"
  ssl_policy        = "ELBSecurityPolicy-TLS-1-2-Ext-2018-06"
  certificate_arn   = var.ssl_cert

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.app_tg[each.key].arn
  }
}

resource "aws_lb_listener_rule" "app_https_listener_rule" {
  for_each     = var.listeners
  listener_arn = aws_lb_listener.app_listener_forward[each.key].arn

  action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.app_tg[each.key].arn
  }

  condition {
    path_pattern {
      values = each.value.paths
    }
  }
}

resource "aws_lb_target_group" "app_tg" {
  for_each    = var.listeners
  name        = each.key
  port        = each.value.app_port
  protocol    = "HTTP"
  target_type = "ip"
  vpc_id      = aws_vpc.app_vpc.id

  health_check {
    interval            = 130
    timeout             = 120
    healthy_threshold   = 10
    unhealthy_threshold = 10
  }

  stickiness {
    type            = "lb_cookie"
    cookie_duration = 86400
  }
}

下面是變量聲明:

variable "listeners" {
  type = map(object({
    app_port  = number
    paths     = set(string)
    listeners = set(number)
  }))
  default = {
    "app_one" = {
       app_port = 3000
       paths = [
         "/appOne",
         "/appOne/*"
       ]
       listeners = [
         80, 443, 22, 7999, 8999
       ]
    }
    "app_two" = {
       app_port = 4000
       paths = [
         "/appTwo",
         "/appTwo/*"
       ]
       listeners = [
         80, 443, 22, 7999, 8999
       ]
    }
  }
}

嘗試執行時,我在處理aws_lb_listener資源的port屬性時遇到錯誤。 以下是錯誤:

Error: Incorrect attribute value type
│
│   on alb.tf line 38, in resource "aws_lb_listener" "app_listener_forward":
│   38:   port              = each.value.listeners
│     ├────────────────
│     │ each.value.listeners is set of string with 5 elements
│
│ Inappropriate value for attribute "port": number required.

由於數字列表,我嘗試將變量的 listeners 屬性設置為一個集合(數字)和一個集合(字符串),但我仍然收到此錯誤。

關於如何修復此錯誤的任何想法都會有所幫助。

謝謝!

錯誤消息指出resource "aws_lb_listener" "app_listener_forward" {..}中端口的值似乎不正確。

由於您已經在使用for_each循環整個資源,因此它不能在用於循環的變量中可用的值內循環。

一種解決方案是將可變listeners器分成兩部分。

第 1 步:將變量分成 2 個變量

隨意使用任何對您來說更有意義的名稱。

variable "listner_ports" {
  type        = list(string)
  description = "(optional) listeners port numbers"
  default = [
    80, 443, 22, 7999, 8999
  ]
}
variable "listeners" {
  type = map(object({
    app_port = number
    paths    = set(string)
  }))
  default = {
    "app-one" = {
      app_port = 3000
      paths = [
        "/appOne",
        "/appOne/*"
      ]
    }
    "app-two" = {
      app_port = 4000
      paths = [
        "/appTwo",
        "/appTwo/*"
      ]
    }
  }
}

注意:我已將app_{one,two}更改為app-{one,two}因為aws_lb_target_group“名稱”中只允許使用字母數字字符和連字符

第 2 步:使用aws_lb_listener中的 terraform 動態塊對同一資源中的不同變量使用循環。

resource "aws_lb_listener" "app_listener_forward" {
  for_each          = toset(var.listner_ports)
  load_balancer_arn = data.aws_lb.test.arn ## Use aws_lb.app_alb.arn as per your usecase
  port              = each.value
  protocol          = "HTTP" # you might need to use a more complex variable to support ports and protocols but it gives an idea.
## Uncommend in your case.
  # ssl_policy        = "ELBSecurityPolicy-TLS-1-2-Ext-2018-06"
  # certificate_arn   = var.ssl_cert

  dynamic "default_action" {
    for_each = var.listeners

    content {
      type             = "forward"
      target_group_arn = aws_lb_target_group.app_tg[default_action.key].arn
    }
  }
}

resource "aws_lb_target_group" "app_tg" {
  for_each    = var.listeners
  name        = each.key
  port        = each.value.app_port
  protocol    = "HTTP"
  target_type = "ip"
  vpc_id      = local.vpc_id

  health_check {
    interval            = 130
    timeout             = 120
    healthy_threshold   = 10
    unhealthy_threshold = 10
  }

  stickiness {
    type            = "lb_cookie"
    cookie_duration = 86400
  }
}

只是為了向您展示它是如何工作的,下面是僅aws_lb_listeneraws_lb_target_group資源的附加計划。

Terraform will perform the following actions:

  # aws_lb_listener.app_listener_forward["22"] will be created
  + resource "aws_lb_listener" "app_listener_forward" {
      + arn               = (known after apply)
      + id                = (known after apply)
      + load_balancer_arn = "arn:aws:elasticloadbalancing:eu-central-1:xxxxxxxxxxxxxx:loadbalancer/app/stackoverflow/be9c11ed9c543788"
      + port              = 22
      + protocol          = "HTTP"
      + ssl_policy        = (known after apply)
      + tags_all          = (known after apply)

      + default_action {
          + order            = (known after apply)
          + target_group_arn = (known after apply)
          + type             = "forward"
        }
      + default_action {
          + order            = (known after apply)
          + target_group_arn = (known after apply)
          + type             = "forward"
        }
    }

  # aws_lb_listener.app_listener_forward["443"] will be created
  + resource "aws_lb_listener" "app_listener_forward" {
      + arn               = (known after apply)
      + id                = (known after apply)
      + load_balancer_arn = "arn:aws:elasticloadbalancing:eu-central-1:xxxxxxxxxxxxxx:loadbalancer/app/stackoverflow/be9c11ed9c543788"
      + port              = 443
      + protocol          = "HTTP"
      + ssl_policy        = (known after apply)
      + tags_all          = (known after apply)

      + default_action {
          + order            = (known after apply)
          + target_group_arn = (known after apply)
          + type             = "forward"
        }
      + default_action {
          + order            = (known after apply)
          + target_group_arn = (known after apply)
          + type             = "forward"
        }
    }

  # aws_lb_listener.app_listener_forward["7999"] will be created
  + resource "aws_lb_listener" "app_listener_forward" {
      + arn               = (known after apply)
      + id                = (known after apply)
      + load_balancer_arn = "arn:aws:elasticloadbalancing:eu-central-1:xxxxxxxxxxxxxx:loadbalancer/app/stackoverflow/be9c11ed9c543788"
      + port              = 7999
      + protocol          = "HTTP"
      + ssl_policy        = (known after apply)
      + tags_all          = (known after apply)

      + default_action {
          + order            = (known after apply)
          + target_group_arn = (known after apply)
          + type             = "forward"
        }
      + default_action {
          + order            = (known after apply)
          + target_group_arn = (known after apply)
          + type             = "forward"
        }
    }

  # aws_lb_listener.app_listener_forward["80"] will be created
  + resource "aws_lb_listener" "app_listener_forward" {
      + arn               = (known after apply)
      + id                = (known after apply)
      + load_balancer_arn = "arn:aws:elasticloadbalancing:eu-central-1:xxxxxxxxxxxxxx:loadbalancer/app/stackoverflow/be9c11ed9c543788"
      + port              = 80
      + protocol          = "HTTP"
      + ssl_policy        = (known after apply)
      + tags_all          = (known after apply)

      + default_action {
          + order            = (known after apply)
          + target_group_arn = (known after apply)
          + type             = "forward"
        }
      + default_action {
          + order            = (known after apply)
          + target_group_arn = (known after apply)
          + type             = "forward"
        }
    }

  # aws_lb_listener.app_listener_forward["8999"] will be created
  + resource "aws_lb_listener" "app_listener_forward" {
      + arn               = (known after apply)
      + id                = (known after apply)
      + load_balancer_arn = "arn:aws:elasticloadbalancing:eu-central-1:xxxxxxxxxxxxxx:loadbalancer/app/stackoverflow/be9c11ed9c543788"
      + port              = 8999
      + protocol          = "HTTP"
      + ssl_policy        = (known after apply)
      + tags_all          = (known after apply)

      + default_action {
          + order            = (known after apply)
          + target_group_arn = (known after apply)
          + type             = "forward"
        }
      + default_action {
          + order            = (known after apply)
          + target_group_arn = (known after apply)
          + type             = "forward"
        }
    }

  # aws_lb_target_group.app_tg["app-one"] will be created
  + resource "aws_lb_target_group" "app_tg" {
      + arn                                = (known after apply)
      + arn_suffix                         = (known after apply)
      + connection_termination             = false
      + deregistration_delay               = "300"
      + id                                 = (known after apply)
      + ip_address_type                    = (known after apply)
      + lambda_multi_value_headers_enabled = false
      + load_balancing_algorithm_type      = (known after apply)
      + name                               = "app-one"
      + port                               = 3000
      + preserve_client_ip                 = (known after apply)
      + protocol                           = "HTTP"
      + protocol_version                   = (known after apply)
      + proxy_protocol_v2                  = false
      + slow_start                         = 0
      + tags_all                           = (known after apply)
      + target_type                        = "ip"
      + vpc_id                             = "vpc-063017c6abb96eab6"

      + health_check {
          + enabled             = true
          + healthy_threshold   = 10
          + interval            = 130
          + matcher             = (known after apply)
          + path                = (known after apply)
          + port                = "traffic-port"
          + protocol            = "HTTP"
          + timeout             = 120
          + unhealthy_threshold = 10
        }

      + stickiness {
          + cookie_duration = 86400
          + enabled         = true
          + type            = "lb_cookie"
        }

      + target_failover {
          + on_deregistration = (known after apply)
          + on_unhealthy      = (known after apply)
        }
    }

  # aws_lb_target_group.app_tg["app-two"] will be created
  + resource "aws_lb_target_group" "app_tg" {
      + arn                                = (known after apply)
      + arn_suffix                         = (known after apply)
      + connection_termination             = false
      + deregistration_delay               = "300"
      + id                                 = (known after apply)
      + ip_address_type                    = (known after apply)
      + lambda_multi_value_headers_enabled = false
      + load_balancing_algorithm_type      = (known after apply)
      + name                               = "app-two"
      + port                               = 4000
      + preserve_client_ip                 = (known after apply)
      + protocol                           = "HTTP"
      + protocol_version                   = (known after apply)
      + proxy_protocol_v2                  = false
      + slow_start                         = 0
      + tags_all                           = (known after apply)
      + target_type                        = "ip"
      + vpc_id                             = "vpc-063017c6abb96eab6"

      + health_check {
          + enabled             = true
          + healthy_threshold   = 10
          + interval            = 130
          + matcher             = (known after apply)
          + path                = (known after apply)
          + port                = "traffic-port"
          + protocol            = "HTTP"
          + timeout             = 120
          + unhealthy_threshold = 10
        }

      + stickiness {
          + cookie_duration = 86400
          + enabled         = true
          + type            = "lb_cookie"
        }

      + target_failover {
          + on_deregistration = (known after apply)
          + on_unhealthy      = (known after apply)
        }
    }

Plan: 7 to add, 0 to change, 0 to destroy.

希望能幫助到你。 並且,是的,我已經屏蔽了帳戶 ID:)。

已編輯

這部分是在閱讀@David 的評論后添加的,他在評論中提到了另一個問題 ERROR Message: "InvalidLoadBalancerAction: You cannot specify multiple of the following action type: 'forward'" when trying to create the listener.

將其用作您的aws_lb_listener的基本代碼,我強烈建議您根據最佳解決方案進行修改。[嵌套動態塊 --> 有關文檔,請參閱此處]


resource "aws_lb_listener" "app_listener_forward" {
  for_each          = toset(var.listner_ports)
  load_balancer_arn = aws_lb.test.arn
  port              = each.value
  protocol          = "HTTP" # you might need to use a more complex variable to support ports and protocols but it gives an idea.
## Uncommend in your case.
  # ssl_policy        = "ELBSecurityPolicy-TLS-1-2-Ext-2018-06"
  # certificate_arn   = var.ssl_cert

  default_action {
    type = "forward"
    forward {
      dynamic "target_group" {
        for_each = var.listeners
        content {
          arn = aws_lb_target_group.app_tg[target_group.key].arn
        }
      }
      stickiness {
        enabled  = true
        duration = 86400
      }
    }
  }
}

結論: Apply 確實按預期使用上述代碼(為具有不同端口的兩個目標組創建了多個偵聽器)但無法確認這是否是您所需要的,但是,可以根據要求調整解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM