Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support ALB advanced request routing #8126

Closed
ewbankkit opened this issue Mar 29, 2019 · 15 comments 路 Fixed by #8268

Comments

@ewbankkit
Copy link
Contributor

@ewbankkit ewbankkit commented Mar 29, 2019

Community Note

  • Please vote on this issue by adding a 馃憤 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Add support for AWS Application Load Balancer advanced request routing.

@ewbankkit

This comment has been minimized.

Copy link
Contributor Author

@ewbankkit ewbankkit commented Apr 2, 2019

It looks like we need to add blocks to the aws_lb_listener_rule.condition attribute:

resource "aws_lb_listener_rule" "foo" {
  condition {
    host_header_config {
    }
  }

  condition {
    http_header_config {
    }
  }

  condition {
    http_request_method_config {
    }
  }

  condition {
    path_pattern_config {
    }
  }

  condition {
    query_string_config {
    }
  }

  condition {
    source_ip_config {
    }
  }
}
@excalq

This comment has been minimized.

Copy link

@excalq excalq commented Apr 6, 2019

Right, in the case of http_header_config, you'll need a header key (e.g. user-agent), and a list of values (OR'd together). This would represent such a configuration:
image

@srhaber

This comment has been minimized.

Copy link
Contributor

@srhaber srhaber commented Apr 10, 2019

Below is my take.

Description

Application Load Balancers now have additional routing options as of 3/27/2019.

Conditions fields:

  • Host header
  • Path
  • HTTP header (new)
  • HTTP request method (new)
  • Query string (new)
  • Source IP (new)

Additionally, each condition can now accept multiple values.

New or Affected Resource(s)

  • aws_alb_listener_rule

Potential Terraform Configuration

resource "aws_lb_listener_rule" "advanced_routing" {
  listener_arn = "${aws_lb_listener.front_end.arn}"
  priority     = 99

  action {
    type             = "forward"
    target_group_arn = "${aws_lb_target_group.static.arn}"
  }

  # Condition field: host-header
  condition {
    field  = "host-header"
    values = ["*.example.com"]
  }

  # Condition field: path-pattern
  condition {
    field  = "path-pattern"
    values = ["/img/*"]
  }

  # New condition field: http-header
  condition {
    field            = "http-header"
    http_header_name = "User-Agent"

    # Multiple values now acceptable
    values = [
      "*Chrome*",
      "*Safari*",
    ] 
  }

  # New condition field: http-request-method
  condition {
    field  = "http-request-method"

    values = [
      "GET",
      "POST"
    ]
  }

  # New condition field: query-string
  condition {
    field = "query-string"

    values = [
      {
        key   = "version"
        value = "v1"
      },
      {
        value = "example"
      }
    ]
  }

  # New condition field: source-ip
  condition {
    field = "source-ip"

    values = [
      "192.0.2.0/24", 
      "198.51.100.10/32",
    ]
  }
}

References

The query-string condition throws a curve by having values be a list of maps instead of a list of strings. Thus, it might be necessary to introduce the extra *_config blocks per condition in accordance with Amazon's API spec. See snippet below for example.

# Common structure specifies a list of strings
[
  {
      "Field": "host-header",
      "HostHeaderConfig": {
          "Values": ["*.example.com"]
      }
  }
]

# Query string specifies a list of maps
[
  {
      "Field": "query-string",
      "QueryStringConfig": {
          "Values": [
            {
                "Key": "version", 
                "Value": "v1"
            },
            {
                "Value": "example"
            }
          ]
      }
  }
]

# HTTP header introduces an additional field for header name
[
  {
      "Field": "http-header",
      "HttpHeaderConfig": {
          "HttpHeaderName": "User-Agent",
          "Values": ["*Chrome*", "*Safari*"]
      }
  }
]
@bharat109puri

This comment has been minimized.

Copy link

@bharat109puri bharat109puri commented May 3, 2019

@ewbankkit Is this feature added.

@ewbankkit

This comment has been minimized.

Copy link
Contributor Author

@ewbankkit ewbankkit commented May 3, 2019

@bharat109puri We are still waiting on #8268 to be reviewed and merged.

@jim-leary

This comment has been minimized.

Copy link

@jim-leary jim-leary commented Aug 14, 2019

Was this (or will it be) back-ported to 0.11.x? Not ready to goto 0.12.x just yet.

@dpiddockcmp

This comment has been minimized.

Copy link
Contributor

@dpiddockcmp dpiddockcmp commented Aug 27, 2019

@jim-leary AWS provider v2 is compatible with both TF 0.11 and 0.12

@RichardBronosky

This comment has been minimized.

Copy link

@RichardBronosky RichardBronosky commented Sep 4, 2019

I'd like to suggest that we model our implementation after the --conditions list JSON format accepted by aws elbv2 modify-rule.

Currently, to get around this shortcoming, I create a simple aws_alb_listener_rule and use its arn to modify it with a local-exec provisioner.

resource "null_resource" "update_rule" {
  provisioner "local-exec" {
    command = <<EOF
      aws elbv2 modify-rule \
        --rule-arn=${aws_lb_listener_rule.example_com_https.arn} \
        --conditions='
          [
            {
              "Field": "host-header",
              "HostHeaderConfig": {
                "Values": [ "www-origin.example.com" ]
              }
            },
            {
              "Field": "http-header",
              "HttpHeaderConfig": {
                "HttpHeaderName": "x-cf-access-identity",
                "Values": [ "${random_uuid.cf_access_identity.result}" ]
              }
            }
          ]
        '
EOF
  }
}

For more info, see:

$ aws elbv2 modify-rule --generate-cli-skeleton
{
    "RuleArn": "",
    "Conditions": [
        {
            "Field": "",
            "Values": [
                ""
            ],
            "HostHeaderConfig": {
                "Values": [
                    ""
                ]
            },
            "PathPatternConfig": {
                "Values": [
                    ""
                ]
            },
            "HttpHeaderConfig": {
                "HttpHeaderName": "",
                "Values": [
                    ""
                ]
            },
            "QueryStringConfig": {
                "Values": [
                    {
                        "Key": "",
                        "Value": ""
                    }
                ]
            },
            "HttpRequestMethodConfig": {
                "Values": [
                    ""
                ]
            },
            "SourceIpConfig": {
                "Values": [
                    ""
                ]
            }
        }
    ],

...
and

$ aws elbv2 modify-rule help | cat
<string>:352: (WARNING/2) Inline emphasis start-string without end-string.
MODIFY-RULE()                                                    MODIFY-RULE()



NAME
       modify-rule -

DESCRIPTION
       Modifies the specified rule.

       Any  existing  properties  that  you do not modify retain their current
       values.

       To modify the actions for the default rule, use  ModifyListener .

       See also: AWS API Documentation

       See 'aws help' for descriptions of global parameters.

SYNOPSIS
            modify-rule
          --rule-arn <value>
          [--conditions <value>]
          [--actions <value>]
          [--cli-input-json <value>]
          [--generate-cli-skeleton <value>]

OPTIONS
       --rule-arn (string)
          The Amazon Resource Name (ARN) of the rule.

       --conditions (list)
          The conditions. Each rule can include zero or one of  the  following
          conditions:  http-request-method  , host-header , path-pattern , and
          source-ip  ,  and  zero  or  more  of  the   following   conditions:
          http-header and query-string .

       JSON Syntax:

          [
            {
              "Field": "string",
              "Values": ["string", ...],
              "HostHeaderConfig": {
                "Values": ["string", ...]
              },
              "PathPatternConfig": {
                "Values": ["string", ...]
              },
              "HttpHeaderConfig": {
                "HttpHeaderName": "string",
                "Values": ["string", ...]
              },
              "QueryStringConfig": {
                "Values": [
                  {
                    "Key": "string",
                    "Value": "string"
                  }
                  ...
                ]
              },
              "HttpRequestMethodConfig": {
                "Values": ["string", ...]
              },
              "SourceIpConfig": {
                "Values": ["string", ...]
              }
            }
            ...
          ]
@driedelreply

This comment has been minimized.

Copy link

@driedelreply driedelreply commented Sep 25, 2019

Is there an ETA for a release of this feature to Terraform?

@Skyfallz

This comment has been minimized.

Copy link

@Skyfallz Skyfallz commented Nov 25, 2019

@aeschright Can we have an update for this one too please ? All these ALB features are absolutely necessary for many of us, and as I said on another ALB related issue, being this late in implementing pretty basic features on widely used resources like ALBs could really become a huge negative point of Terraform.

@dfens1

This comment has been minimized.

Copy link

@dfens1 dfens1 commented Nov 25, 2019

While in general, the AWS provider plugin is updated very promptly with new features as they become available in AWS (like QLDB), this one is a big outlier. Is there any explanation why this is the case? Just trying to get a better idea for future features..

@dpiddockcmp

This comment has been minimized.

Copy link
Contributor

@dpiddockcmp dpiddockcmp commented Nov 26, 2019

The feedback loop with TF aws provider maintainers has been really slow. It's also my first attempt at a change of this size, so the first code was not great 馃槄 . Probably explains some of their disinterest in the PR.

The first official reviewer was a new hire also and didn't know the code base. There was a bit of back-and-forth with requests for changes that are simply impossible in terraform. Wasted a lot of my time and murdered motivation. By the time he was happy with the PR he had lost commit permissions to the provider repo.

A new reviewer has asked for more changes, some of which are regressions to earlier versions. I just need to find the time and motivation to do the work. Any changes to the code base requires updating a lot of tests. Which is slow and painful due to needing to generate the set hashes. Running the ALB rules test suite is very time consuming.

@emmm-dee

This comment has been minimized.

Copy link

@emmm-dee emmm-dee commented Dec 2, 2019

need to find the time and motivation to do the work.

Can I send you $$$ for motivation?

@dfens1

This comment has been minimized.

Copy link

@dfens1 dfens1 commented Dec 2, 2019

@dpiddockcmp can you provide some sort of estimate how much work is left to completion or even a time estimate? We're pretty desperately waiting for this feature since we just dropped the serverless framework and API Gateway. We just totally didn't expect this not to be already available in the provider plugin - and yes, I should've checked first :(

@dpiddockcmp

This comment has been minimized.

Copy link
Contributor

@dpiddockcmp dpiddockcmp commented Dec 3, 2019

Unfortunately it's impossible to give a time estimate. I've made changes from the last round of review so now it's back to the maintainers.

aeschright added a commit that referenced this issue Dec 6, 2019
@aeschright aeschright added this to the v2.42.0 milestone Dec 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can鈥檛 perform that action at this time.