This Terraform Module provides a simpler, more declarative interface for creating
Load Balancer Listener Rules
that determine how the load balancer routes requests to its registered targets. It's an alternative to creating
lb_listener_rule resources directly in
Terraform, which can be convenient, for example, when configuring listener rules in a
Terragrunt configuration.
This module currently supports:
Most major rule types: forward rules, redirect rules, fixed-response
See variables.tf for all the variables you can set on this module.
Gotcha's
Make sure your Listeners handle all possible request paths
An LB Listener
represents an open port on your ALB, waiting to receive requests and route them to a Target
Group.
Suppose you want to have this LB Listener route requests for /foo to ServiceFoo and requests for /bar to ServiceBar.
You'd accomplish this creating two LB Listener
Rules as follows:
Route /foo traffic to Target Group ServiceFoo
Route /bar traffic to Target Group ServiceBar
So far so good. But what if the Listener receives a request for /hello? Since no Listener Rule handles that path, the
LB needs to handle it with a default action. The default action in the ALB module, for example, returns a fixed response, which
by default is a blank 404 page. You can also add an ALB Listener Rule that catches ALL requests (i.e., *) and have that
rule forward to a custom Target Group so your own apps can respond in any way you wish.
Make sure your Listener Rules each have a unique "priority"
See the prior section understand what Listener Rules are.
When defining a Listener Rule, you must specify both a priority and a path. The priority tells the ALB in what priority
a particular Listener Rule should be evaluated. For example, suppose you have the following Listener Rules defined on
your ALB:
Route /foo traffic to Target Group ServiceFoo
Route /foo* traffic to Target Group ServiceBar
To which Target Group should a request for /foo be routed? Based on the above, it's non-determinate. For this reason,
you must include a "priority" in the Listener Rule. A priority is an integer value where the lower the number the higher
the priority. For example, if we add in priorities to our Listener Rules:
Priority: 100. Route /foo traffic to Target Group ServiceFoo
Priority: 200. Route /foo* traffic to Target Group ServiceBar
Now we know that the first Listener Rule has a higher priority. That means that requests for /foo will be routed to
ServiceFoo, while all other requests will be routed to ServiceBar.
The gotcha here is that, because you define the Listener Rules for a single Listener across potentially many different
ECS Services or Auto Scaling Groups, take care to make sure that each Listener Rule uses a globally unique priority number.
Note that in most cases, your path definitions should be mutually exclusive and the actual priority value won't matter.
Questions? Ask away.
We're here to talk about our services, answer any questions, give advice, or just to chat.
{"treedata":{"name":"root","toggled":true,"children":[{"name":".circleci","children":[{"name":"config.yml","path":".circleci/config.yml","sha":"17fa639a1f8685ba634afd3611da0681d61c8f9c"}]},{"name":".gitignore","path":".gitignore","sha":"8530ecdd5eddb0e1c3a9f93d106dd2e53e0cebd6"},{"name":".pre-commit-config.yaml","path":".pre-commit-config.yaml","sha":"0e5d25938de5c5a930042658bc08da08c707a072"},{"name":"CODEOWNERS","path":"CODEOWNERS","sha":"8c24c86ef8447a19436b38826f458c71b4da4f45"},{"name":"LICENSE.txt","path":"LICENSE.txt","sha":"154ea4429924fda533b20544c7a19d8949fc82cf"},{"name":"README.md","path":"README.md","sha":"6ac250f1db253563684b3bd8d4b3ae7b79a29025"},{"name":"examples","children":[{"name":"acm-tls-certificate","children":[{"name":"README.md","path":"examples/acm-tls-certificate/README.md","sha":"0a7892a8b5d327254c91a96276273fcc975821ca"},{"name":"dependencies.tf","path":"examples/acm-tls-certificate/dependencies.tf","sha":"237767e8323ffdf0d76a976946fa24c4f12708ce"},{"name":"main.tf","path":"examples/acm-tls-certificate/main.tf","sha":"33193b28652a4185b4fe78d1e6043f6484023199"},{"name":"outputs.tf","path":"examples/acm-tls-certificate/outputs.tf","sha":"083ef125b3be1f465c66f8b1e8b0ede0c782f10e"},{"name":"vars.tf","path":"examples/acm-tls-certificate/vars.tf","sha":"3b96d4f8aa3d1620494d05538069dbc5d9d4de14"}]},{"name":"alb-with-logs","children":[{"name":"README.md","path":"examples/alb-with-logs/README.md","sha":"b46a1aef114340b80c6742b9344c52f1a952a7a4"},{"name":"main.tf","path":"examples/alb-with-logs/main.tf","sha":"7be449ee5bd07192f61ae2624cc4d6c30b4a75a9"},{"name":"outputs.tf","path":"examples/alb-with-logs/outputs.tf","sha":"518914d6b608ea2d2996cbaa9361c370bd9c9fa1"},{"name":"vars.tf","path":"examples/alb-with-logs/vars.tf","sha":"029a4cf53d07f1e6e5c04c6173df8a29b0bed98f"}]},{"name":"alb","children":[{"name":"README.md","path":"examples/alb/README.md","sha":"202d51dd9238a27061a6277a4632dce37706a3f9"},{"name":"main.tf","path":"examples/alb/main.tf","sha":"b4ff256e079e2849494e976282c6b007de3c8f60"},{"name":"outputs.tf","path":"examples/alb/outputs.tf","sha":"201a421be76f8332b212f78216417e35f8c968eb"},{"name":"vars.tf","path":"examples/alb/vars.tf","sha":"3306c4227949373dc9fed5a83dc19f7d6904e007"}]},{"name":"lb-listener-rules","children":[{"name":"README.md","path":"examples/lb-listener-rules/README.md","sha":"3d2205b57641d6e97bc28f2a8a59093c4bfc7f61"},{"name":"main.tf","path":"examples/lb-listener-rules/main.tf","sha":"dfa7c2228c5e674636204806d7d96bddbd6ce891"},{"name":"outputs.tf","path":"examples/lb-listener-rules/outputs.tf","sha":"2f227fe908f34ad51a837a85fa6a064f993fa897"},{"name":"user_data.sh","path":"examples/lb-listener-rules/user_data.sh","sha":"5b667c100463a2ce64a5827e4e9dc357509e1a4c"},{"name":"variables.tf","path":"examples/lb-listener-rules/variables.tf","sha":"6fd908ad8227c3e2b1058a3b752d245aef0c1b5f"}]},{"name":"multiple-acm-tls-certificates","children":[{"name":"main.tf","path":"examples/multiple-acm-tls-certificates/main.tf","sha":"6dbd35fe21a5b4f92b57c217f524f98f83dc3f2b"},{"name":"outputs.tf","path":"examples/multiple-acm-tls-certificates/outputs.tf","sha":"20ec52f607e69887ce2a0b54e68415cf36f034e6"},{"name":"vars.tf","path":"examples/multiple-acm-tls-certificates/vars.tf","sha":"55bb61a54afca24f007dfdf2aed50fb86355d56a"}]}]},{"name":"modules","children":[{"name":"acm-tls-certificate","children":[{"name":"README.md","path":"modules/acm-tls-certificate/README.md","sha":"3a5873e77d9ab92ef6b43545d577ac5911b777c7"},{"name":"main.tf","path":"modules/acm-tls-certificate/main.tf","sha":"4fa24dec4849e72f6554a84c62f970fdfca61797"},{"name":"outputs.tf","path":"modules/acm-tls-certificate/outputs.tf","sha":"18fa9f9ce0d23ca8f81f8fa41cb20c81922f7a87"},{"name":"vars.tf","path":"modules/acm-tls-certificate/vars.tf","sha":"ca6385fbb1865ee150851f3ee165021a6712b45d"},{"name":"wait-until-tls-cert-not-in-use.sh","path":"modules/acm-tls-certificate/wait-until-tls-cert-not-in-use.sh","sha":"68296e34cc4e86fbefcae3820e6de88f2aa6f911"}]},{"name":"alb","children":[{"name":"README.md","path":"modules/alb/README.md","sha":"3f749a16fbe8484b7c3b56a4f980f3c470c4da1f"},{"name":"main.tf","path":"modules/alb/main.tf","sha":"7d6c3d2dbacef0542de5be088516ec0034754aef"},{"name":"outputs.tf","path":"modules/alb/outputs.tf","sha":"e1de70ae961208480de17161a71e1ff86d96f612"},{"name":"vars.tf","path":"modules/alb/vars.tf","sha":"b7ea99986b18399073d1610476c3adbf20ea38b6"}]},{"name":"lb-listener-rules","children":[{"name":"README.md","path":"modules/lb-listener-rules/README.md","sha":"a4a3c1a510f7958373a35ba409a6ce4eb5ba63eb","toggled":true},{"name":"listener-rules-list-to-map","children":[{"name":"README.md","path":"modules/lb-listener-rules/listener-rules-list-to-map/README.md","sha":"2a61caf06789c48011607cb7976da736bfa61aaf"},{"name":"outputs.tf","path":"modules/lb-listener-rules/listener-rules-list-to-map/outputs.tf","sha":"7c4311be9c8a1d6585093227949ad3e9fbe27073"},{"name":"variables.tf","path":"modules/lb-listener-rules/listener-rules-list-to-map/variables.tf","sha":"1f81e857a5725d04cc8d3028a3d7e062bac19216"}]},{"name":"main.tf","path":"modules/lb-listener-rules/main.tf","sha":"354d40ee5fa34c043d9114a4b89348ba9778f602"},{"name":"outputs.tf","path":"modules/lb-listener-rules/outputs.tf","sha":"9d3efd16064ff8defdb7e8c95634f875d10832b1"},{"name":"variables.tf","path":"modules/lb-listener-rules/variables.tf","sha":"bef3aceb1f79bc43f5708163ebef0e9d210dc6db"}],"toggled":true},{"name":"nlb","children":[{"name":"README.md","path":"modules/nlb/README.md","sha":"254a0821c57aaf051690b99f3d2fea939aa8ad80"}]}],"toggled":true},{"name":"terraform-cloud-enterprise-private-module-registry-placeholder.tf","path":"terraform-cloud-enterprise-private-module-registry-placeholder.tf","sha":"ae586c0fe830819580e1009d41a9074f16e65bed"},{"name":"test","children":[{"name":"README.md","path":"test/README.md","sha":"ded6aae1d95e6fca858a0ef196d3ecf30d4bf5f2"},{"name":"acm_tls_certificate_test.go","path":"test/acm_tls_certificate_test.go","sha":"2d517d87b6787f525d2e72855c6da7d8232c8e0c"},{"name":"go.mod","path":"test/go.mod","sha":"6325ef2b3b26198f4976d0447f9420165d6f5788"},{"name":"go.sum","path":"test/go.sum","sha":"26a9de4c5e22e7f032c7f64869adb0853aa920e9"},{"name":"lb_listener_rules_test.go","path":"test/lb_listener_rules_test.go","sha":"58566294d86546cf3bb5771ff09d8987df5ccd7b"},{"name":"lb_test.go","path":"test/lb_test.go","sha":"be64434cbd9ee3b91fe85b2d5596990fa17eb56f"},{"name":"validation","children":[{"name":"validate_all_modules_and_examples_test.go","path":"test/validation/validate_all_modules_and_examples_test.go","sha":"33d73c385b64c4fc870033e99427e683c31dc45a"}]}]}]},"detailsContent":"<h1 class=\"preview__body--title\" id=\"load-balancer-listener-rules\">Load Balancer Listener Rules</h1><div class=\"preview__body--border\"></div><p>This Terraform Module provides a simpler, more declarative interface for creating\n<a href=\"https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-listeners.html\" class=\"preview__body--description--blue\" target=\"_blank\">Load Balancer Listener Rules</a>\nthat determine how the load balancer routes requests to its registered targets. It's an alternative to creating\n<a href=\"https://www.terraform.io/docs/providers/aws/r/lb_listener_rule.html\" class=\"preview__body--description--blue\" target=\"_blank\"><code>lb_listener_rule</code></a> resources directly in\nTerraform, which can be convenient, for example, when configuring listener rules in a\n<a href=\"https://terragrunt.gruntwork.io/\" class=\"preview__body--description--blue\" target=\"_blank\">Terragrunt configuration</a>.</p>\n<p>This module currently supports:</p>\n<ul>\n<li>Most major rule types: forward rules, redirect rules, fixed-response</li>\n<li>Most condition types: host header, HTTP header, request method, path pattern, query string, source IP.</li>\n</ul>\n<p>This module does NOT currently support:</p>\n<ul>\n<li><code>authenticate_cognito</code> and <code>authenticate_oidc</code> rules</li>\n</ul>\n<p>This feature may be added later, but if you need them now, you should use the\n<a href=\"https://www.terraform.io/docs/providers/aws/r/lb_listener_rule.html\" class=\"preview__body--description--blue\" target=\"_blank\"><code>lb_listener_rule</code></a> resource directly.</p>\n<h2 class=\"preview__body--subtitle\" id=\"how-do-you-use-this-module\">How do you use this module?</h2>\n<ul>\n<li>See the <a href=\"/repos/v0.29.2/module-load-balancer/README.md\" class=\"preview__body--description--blue\">root README</a> for instructions on using Terraform modules.</li>\n<li>See the <a href=\"/repos/v0.29.2/module-load-balancer/examples\" class=\"preview__body--description--blue\">examples</a> folder for example usage.</li>\n<li>See <a href=\"/repos/v0.29.2/module-load-balancer/modules/lb-listener-rules/variables.tf\" class=\"preview__body--description--blue\">variables.tf</a> for all the variables you can set on this module.</li>\n</ul>\n<h2 class=\"preview__body--subtitle\" id=\"gotchas\">Gotcha's</h2>\n<h3 class=\"preview__body--subtitle\" id=\"make-sure-your-listeners-handle-all-possible-request-paths\">Make sure your Listeners handle all possible request paths</h3>\n<p>An <a href=\"http://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-listeners.html\" class=\"preview__body--description--blue\" target=\"_blank\">LB Listener</a>\nrepresents an open port on your ALB, waiting to receive requests and route them to a <a href=\"http://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-target-groups.html\" class=\"preview__body--description--blue\" target=\"_blank\">Target\nGroup</a>.</p>\n<p>Suppose you want to have this LB Listener route requests for <code>/foo</code> to ServiceFoo and requests for <code>/bar</code> to ServiceBar.\nYou'd accomplish this creating two <a href=\"http://docs.aws.amazon.com/elasticloadbalancing/latest/application/listener-update-rules.html\" class=\"preview__body--description--blue\" target=\"_blank\">LB Listener\nRules</a> as follows:</p>\n<ul>\n<li>Route <code>/foo</code> traffic to Target Group ServiceFoo</li>\n<li>Route <code>/bar</code> traffic to Target Group ServiceBar</li>\n</ul>\n<p>So far so good. But what if the Listener receives a request for <code>/hello</code>? Since no Listener Rule handles that path, the\nLB needs to handle it with a default action. The default action in <a href=\"/repos/terraform-aws-load-balancer/modules/alb/main.tf#L50-L89\" class=\"preview__body--description--blue\">the ALB module</a>, for example, returns a fixed response, which\nby default is a blank 404 page. You can also add an ALB Listener Rule that catches ALL requests (i.e., <code>*</code>) and have that\nrule forward to a custom Target Group so your own apps can respond in any way you wish.</p>\n<h3 class=\"preview__body--subtitle\" id=\"make-sure-your-listener-rules-each-have-a-unique-priority\">Make sure your Listener Rules each have a unique "priority"</h3>\n<p>See the <a href=\"#make-sure-your-listeners-handle-all-possible-request-paths\" class=\"preview__body--description--blue\">prior section</a> understand what Listener Rules are.</p>\n<p>When defining a Listener Rule, you must specify both a priority and a path. The priority tells the ALB in what priority\na particular Listener Rule should be evaluated. For example, suppose you have the following Listener Rules defined on\nyour ALB:</p>\n<ul>\n<li>Route <code>/foo</code> traffic to Target Group ServiceFoo</li>\n<li>Route <code>/foo*</code> traffic to Target Group ServiceBar</li>\n</ul>\n<p>To which Target Group should a request for <code>/foo</code> be routed? Based on the above, it's non-determinate. For this reason,\nyou must include a "priority" in the Listener Rule. A priority is an integer value where the lower the number the higher\nthe priority. For example, if we add in priorities to our Listener Rules:</p>\n<ul>\n<li>Priority: 100. Route <code>/foo</code> traffic to Target Group ServiceFoo</li>\n<li>Priority: 200. Route <code>/foo*</code> traffic to Target Group ServiceBar</li>\n</ul>\n<p>Now we know that the first Listener Rule has a higher priority. That means that requests for <code>/foo</code> will be routed to\nServiceFoo, while all other requests will be routed to ServiceBar.</p>\n<p>The gotcha here is that, because you define the Listener Rules for a single Listener across potentially many different\nECS Services or Auto Scaling Groups, take care to make sure that each Listener Rule uses a globally unique priority number.</p>\n<p>Note that in most cases, your path definitions should be mutually exclusive and the actual priority value won't matter.</p>\n","repoName":"module-load-balancer","repoRef":"v0.27.1","serviceDescriptor":{"serviceName":"Elastic Load Balancer (ELB)","serviceRepoName":"module-load-balancer","serviceRepoOrg":"gruntwork-io","cloudProviders":["aws"],"description":"Deploy the Application Load Balancer (ALB) for load balancing HTTP and HTTPS, with support for routing rules and WebSockets.","imageUrl":"elastic.png","licenseType":"subscriber","technologies":["Terraform"],"compliance":[],"tags":[""]},"serviceCategoryName":"Networking","fileName":"README.md","filePath":"/modules/lb-listener-rules","title":"Repo Browser: Elastic Load Balancer (ELB)","description":"Browse the repos in the Gruntwork Infrastructure as Code Library."}