You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Terraform正确配置AWS Elastic Beanstalk ALB默认监听器?

Terraform配置Elastic Beanstalk默认HTTP监听器的SSL策略错误问题

我在用Terraform配置Elastic Beanstalk环境时,想把ALB的默认80端口监听器转发到名为"redirect"的进程(而非默认的"default"进程)。该监听器采用HTTP协议,本不需要SSL配置,但应用配置时AWS持续报错:

Updating Load Balancer listener ... failed Reason: Resource handler returned message: "SSL policy cannot be empty"

我通过aws_elastic_beanstalk_configuration_template创建配置模板并关联到环境,尝试将SSLPolicy和SSLCertificateArns设为空字符串、null或不配置,都会触发上述错误;如果设置实际SSL值,AWS又提示HTTP监听器不能配置SSL策略。


补充上下文

相关配置片段(动态模块)

resource "aws_elastic_beanstalk_configuration_template" "env_template" {
  
  ...

  # Dynamic load balancer listeners
  dynamic "setting" {
    for_each = var.listeners

    content {
      name      = "DefaultProcess"
      namespace = setting.value["port"] == "80" ? "aws:elbv2:listener:default" : "aws:elbv2:listener:${setting.value["port"]}"
      value     = setting.value["process"]
    }
  }
  dynamic "setting" {
    for_each = var.listeners

    content {
      name      = "Protocol"
      namespace = setting.value["port"] == "80" ? "aws:elbv2:listener:default" : "aws:elbv2:listener:${setting.value["port"]}"
      value     = setting.value["protocol"]
    }
  }
  dynamic "setting" {
    for_each = var.listeners

    content {
      name      = "ListenerEnabled"
      namespace = setting.value["port"] == "80" ? "aws:elbv2:listener:default" : "aws:elbv2:listener:${setting.value["port"]}"
      value     = setting.value["enabled"]
    }
  }
  dynamic "setting" {
    for_each = [
      for listener in var.listeners : listener
      if listener.protocol == "HTTPS"
    ]

    content {
      name      = "SSLCertificateArns"
      namespace = setting.value["port"] == "80" ? "aws:elbv2:listener:default" : "aws:elbv2:listener:${setting.value["port"]}"
      value     = setting.value["ssl_cert_arn"]
    }
  }
  dynamic "setting" {
    for_each = [
      for listener in var.listeners : listener
      if listener.protocol == "HTTPS"
    ]

    content {
      name      = "SSLPolicy"
      namespace = setting.value["port"] == "80" ? "aws:elbv2:listener:default" : "aws:elbv2:listener:${setting.value["port"]}"
      value     = setting.value["ssl_policy"]
    }
  }

...
}
resource "aws_elastic_beanstalk_environment" "env" {
  count = 2

  name        = element(var.environment_names, count.index)
  application = var.application_name

  tier                   = "WebServer"
  wait_for_ready_timeout = "20m"
  template_name          = aws_elastic_beanstalk_configuration_template.env_template.name
}

Terraform状态文件中的默认监听器配置

{
  "name": "DefaultProcess",
  "namespace": "aws:elbv2:listener:default",
  "resource": null,
  "value": "redirect"
},
{
  "name": "ListenerEnabled",
  "namespace": "aws:elbv2:listener:default",
  "resource": null,
  "value": "true"
},
{
  "name": "Protocol",
  "namespace": "aws:elbv2:listener:default",
  "resource": null,
  "value": "HTTP"
}

S3中保存的配置(Terraform生成)

aws:elbv2:listener:default:
    ListenerEnabled: true
    SSLPolicy: ''
    SSLCertificateArns: ''
    DefaultProcess: redirect
    Protocol: HTTP

控制台手动配置后保存的文件

:default.aws:elbv2:listener:default:
    ListenerEnabled: true
    DefaultProcess: redirect

我无法让Terraform生成和控制台一致的正确配置。


解决方案

原因分析

Terraform的EB配置模板资源会自动填充未显式设置的SSL相关参数为空字符串,而AWS EB API对默认HTTP监听器的处理逻辑是:如果存在SSLPolicy或SSLCertificateArns参数(哪怕是空值),就会尝试验证SSL配置,导致冲突错误。

解决步骤

  1. 针对默认监听器单独处理,跳过SSL配置项
    修改动态配置块,对默认80端口的HTTP监听器,完全跳过SSL相关的setting块,仅为非默认的HTTPS监听器添加SSL配置:

    # 仅为非默认的HTTPS监听器添加SSL配置
    dynamic "setting" {
      for_each = [
        for listener in var.listeners : listener
        if listener.protocol == "HTTPS" && listener.port != "80"
      ]
    
      content {
        name      = "SSLCertificateArns"
        namespace = "aws:elbv2:listener:${setting.value["port"]}"
        value     = setting.value["ssl_cert_arn"]
      }
    }
    dynamic "setting" {
      for_each = [
        for listener in var.listeners : listener
        if listener.protocol == "HTTPS" && listener.port != "80"
      ]
    
      content {
        name      = "SSLPolicy"
        namespace = "aws:elbv2:listener:${setting.value["port"]}"
        value     = setting.value["ssl_policy"]
      }
    }
    
  2. 确保默认监听器的Protocol显式设为HTTP
    维持现有显式配置,避免Terraform隐式修改该参数。

  3. 强制刷新配置模板
    执行以下命令重新生成配置模板并部署:

    terraform destroy -target aws_elastic_beanstalk_configuration_template.env_template
    terraform apply
    

验证

部署完成后,从S3下载EB配置文件,应该和控制台手动配置的格式一致,不再包含SSLPolicy和SSLCertificateArns空值项,同时默认监听器可正常转发到"redirect"进程。


内容的提问来源于stack exchange,提问作者Chris.B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 17:40:32