如何使aws_lb_listener的default_action动态化

61次阅读
没有评论

问题描述

在使用Terraform创建一组统一的服务器(如EC2、S3等)时遇到了问题。他们需要根据特定的组设置负载均衡器的不同操作,但是他们无法找到解决方法。
具体来说,用户的常见设置如下:

resource "aws_alb_listener" "listener_https" {
  load_balancer_arn = aws_alb.alb.arn
  port = "443"
  protocol = "HTTPS"
  ssl_policy = "ELBSecurityPolicy-FS-1-2-Res-2019-08"
  certificate_arn = data.aws_acm_certificate.main.arn
  default_action {
    target_group_arn = aws_alb_target_group.group.arn
    type = "forward"
  }
}

但在某些情况下,用户需要将默认操作设置为重定向而不是转发。
用户尝试使用dynamic "default_action"块来解决问题,但似乎无法找到同时设置字段名称和值的方法(这可能意味着这不是正确的方法,如果是这样,他希望知道正确的方法是什么)。
用户的问题也可以概括为“(如何)将给定资源的所有值定义为单个值,然后应用它们”(相当于在Python中使用准备好所需值的字典,然后使用**dict创建对象)。

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

用户找到了一个解决方案,虽然不确定是否是最佳解决方案,但对他的情况来说已经足够好了。
解决方案分为三个部分:首先,用户添加了一个变量来提供适用于大多数情况的默认值:

variable "default_lb_action" {
  default = {
    "production": {"type": "forward"}
    "staging": {"type": "forward"}
  }
}

然后,用户添加了一个新的local变量,如下所示:

locals {
  lb_default_action = {
    type = var.default_lb_action[local.environment].type
    target_group_arn = var.default_lb_action[local.environment].type == "forward" ? lookup(var.default_lb_action[local.environment], "target_group_arn", aws_alb_target_group.group.arn) : null
    redirect = try(var.default_lb_action[local.environment].redirect, [])
  }
}

请注意,用户保留了显式声明target_group_arn的选项,这可能是一个要求,也可能不是要求,并且重定向默认为空列表。
最后一步是负载均衡器监听器定义本身,现在看起来像这样:

resource "aws_alb_listener" "listener_https" {
  load_balancer_arn = aws_alb.alb.arn
  port = "443"
  protocol = "HTTPS"
  ssl_policy = "ELBSecurityPolicy-FS-1-2-Res-2019-08"
  certificate_arn = data.aws_acm_certificate.main.arn
  default_action {
    type = local.lb_default_action.type
    target_group_arn = local.lb_default_action.target_group_arn
    dynamic "redirect" {
      for_each = local.lb_default_action.redirect
      iterator = redir
      content {
        host = redir.value["host"]
        path = redir.value["path"]
        port = redir.value["port"]
        protocol = redir.value["protocol"]
        query = redir.value["query"]
        status_code = redir.value["status_code"]
      }
    }
  }
}

重要的是,target_group_arn可以为null(如果type不是"forward"),而且redirect块也可以为空。
通过上述方法,用户可以设置一个变量,并获得所需的结果:

default_lb_action = {
  production = {
    type = "redirect"
    redirect = [
      {
        host = "www.example.com"
        path = "/#{path}"
        port = "#{port}"
        protocol = "HTTPS"
        query = "#{query}"
        status_code = "HTTP_301"
      }
    ]
  }
  staging = {"type": "forward"}
}

希望这对其他人有所帮助!

正文完