Skip to content

in aws_lb_listener_rule incompatible condition blocks are mergedΒ #413

@FlorinAndrei

Description

@FlorinAndrei

Description

In v10.0.0 the way aws_lb_listener_rule resources are created has changed. Now multiple conditions are merged into a single condition block, which may trigger an error on apply.

  • βœ‹ I have searched the open/closed issues and my issue is not listed.

Versions

  • Module version [Required]: v10.0.0

  • Terraform version: OpenTofu v1.10.6

  • Provider version(s): AWS provider 6.13.0

Reproduction Code [Required]

I'm actually using Terragrunt to invoke your module, but that's not relevant. Here is the listeners section, and please look at the conditions in the callrail rule, that's the only part that matters:

  listeners = {
    https_443 = {
      port = 443
      protocol = "HTTPS"
      certificate_arn = local.tls_certificate_arn
      ssl_policy = "ELBSecurityPolicy-TLS13-1-2-Res-2021-06"

      rules = {
        callrail = {
          priority = 1
          actions = [
            {
              forward = {
                target_group_key = "callrail"
              }
            }
          ]
          conditions = [{
            path_pattern = {
              values = ["/calls/call_rail/*"]
            },
            host_header = {
              values = ["integrations.${local.env_domain_short}.${local.dns_domain_main}"]
            }
          }]
          tags = {
            Name = "callrail"
          }
        },
        zapier = {
          priority = 2
          actions = [
            {
              forward = {
                target_group_key = "zapier"
              }
            }
          ]
          conditions = [{
            path_pattern = {
              values = ["/zapier/*"]
            },
            host_header = {
              values = ["integrations.${local.env_domain_short}.${local.dns_domain_main}"]
            }
          }]
          tags = {
            Name = "zapier"
          }
        },
        campdigital = {
          priority = 3
          actions = [
            {
              forward = {
                target_group_key = "campdigital"
              }
            }
          ]
          conditions = [{
            path_pattern = {
              values = ["/camp_digital/*"]
            },
            host_header = {
              values = ["integrations.${local.env_domain_short}.${local.dns_domain_main}"]
            }
          }]
          tags = {
            Name = "campdigital"
          }
        },
        code404 = {
          priority = 4
          actions = [
            {
              fixed_response = {
                content_type = "text/plain"
                status_code = "404"
                message_body = null
              }
            }
          ]
          conditions = [{
            host_header = {
              values = ["integrations.${local.env_domain_short}.${local.dns_domain_main}"]
            }
          }]
          tags = {
            Name = "code404"
          }
        },
      }
      forward = {
        target_group_key = "api"
      }
      tags = {
        Name = "${local.name}-https_443"
      }
    },
    http_80 = {
      port = 80
      protocol = "HTTP"
      forward = {
        target_group_key = "api"
      }
      tags = {
        Name = "${local.name}-http_80"
      }
    }
  }

There are two conditions in that rule, based on host_header and path_pattern. I have this ALB created with module v9.17.0 and it works fine. The rule has two conditions joined with an AND operator.

But if I try to upgrade to v10.0.0 then the apply command fails.

Expected behavior

The apply command should do the changes from v9.17.0 to v10.0.0 which are quite minimal (tags and outputs).

Actual behavior

The apply command fails with:

Error: Only one of host_header, http_header, http_request_method, path_pattern, query_string or source_ip can be set in a condition block

Terminal Output Screenshot(s)

12:39:59.673 STDOUT tofu: OpenTofu will perform the following actions:
12:39:59.673 STDOUT tofu:   # aws_lb_listener_rule.this["https_443/callrail"] will be updated in-place
12:39:59.673 STDOUT tofu:   ~ resource "aws_lb_listener_rule" "this" {
12:39:59.673 STDOUT tofu:         id           = "arn:aws:elasticloadbalancing:us-east-1:XXXXXXXXXXXXXX:listener-rule/XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
12:39:59.673 STDOUT tofu:         tags         = {
12:39:59.673 STDOUT tofu:             "Name"                  = "callrail"
12:39:59.673 STDOUT tofu:             "account"               = "staging"
12:39:59.673 STDOUT tofu:             "env"                   = "staging"
12:39:59.673 STDOUT tofu:             "region"                = "us-east-1"
12:39:59.673 STDOUT tofu:             "terraform"             = "true"
12:39:59.673 STDOUT tofu:             "terraform-aws-modules" = "alb"
12:39:59.673 STDOUT tofu:         }
12:39:59.673 STDOUT tofu:         # (5 unchanged attributes hidden)
12:39:59.673 STDOUT tofu:       - condition {
12:39:59.673 STDOUT tofu:           - host_header {
12:39:59.673 STDOUT tofu:               - values = [
12:39:59.673 STDOUT tofu:                   - "integrations.XXXXXXXXXXXXXXX",
12:39:59.673 STDOUT tofu:                 ] -> null
12:39:59.673 STDOUT tofu:             }
12:39:59.673 STDOUT tofu:         }
12:39:59.673 STDOUT tofu:       - condition {
12:39:59.673 STDOUT tofu:           - path_pattern {
12:39:59.673 STDOUT tofu:               - values = [
12:39:59.673 STDOUT tofu:                   - "/calls/call_rail/*",
12:39:59.673 STDOUT tofu:                 ] -> null
12:39:59.673 STDOUT tofu:             }
12:39:59.673 STDOUT tofu:         }
12:39:59.673 STDOUT tofu:       + condition {
12:39:59.673 STDOUT tofu:           + host_header {
12:39:59.673 STDOUT tofu:               + values = [
12:39:59.673 STDOUT tofu:                   + "integrations.XXXXXXXXXXXXXXXXXX",
12:39:59.673 STDOUT tofu:                 ]
12:39:59.673 STDOUT tofu:             }
12:39:59.673 STDOUT tofu:           + path_pattern {
12:39:59.673 STDOUT tofu:               + values = [
12:39:59.673 STDOUT tofu:                   + "/calls/call_rail/*",
12:39:59.673 STDOUT tofu:                 ]
12:39:59.673 STDOUT tofu:             }
12:39:59.673 STDOUT tofu:         }
12:39:59.673 STDOUT tofu:         # (1 unchanged block hidden)
12:39:59.673 STDOUT tofu:     }

Notice how it tries to merge the two condition blocks there, which is not allowed.

Additional context

The documentation says multiple condition blocks can be declared. It is not necessary to merge the blocks.

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener_rule

Quote: Multiple condition blocks of different types can be set and all must be satisfied for the rule to match.

Quote: Exactly one of host_header, http_header, http_request_method, path_pattern, query_string or source_ip must be set per condition.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions