{"id":35389670,"url":"https://github.com/thobiast/terraform-openstack-loadbalancer","last_synced_at":"2026-01-02T08:02:22.750Z","repository":{"id":45397846,"uuid":"206624149","full_name":"thobiast/terraform-openstack-loadbalancer","owner":"thobiast","description":"Terraform module to create an OpenStack Load Balancer.","archived":false,"fork":false,"pushed_at":"2025-11-14T14:40:38.000Z","size":44,"stargazers_count":6,"open_issues_count":0,"forks_count":7,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-11-14T16:22:21.827Z","etag":null,"topics":["openstack","terraform","terraform-module"],"latest_commit_sha":null,"homepage":null,"language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thobiast.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-09-05T17:47:32.000Z","updated_at":"2025-11-14T14:35:17.000Z","dependencies_parsed_at":"2022-09-03T13:01:02.525Z","dependency_job_id":null,"html_url":"https://github.com/thobiast/terraform-openstack-loadbalancer","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/thobiast/terraform-openstack-loadbalancer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thobiast%2Fterraform-openstack-loadbalancer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thobiast%2Fterraform-openstack-loadbalancer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thobiast%2Fterraform-openstack-loadbalancer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thobiast%2Fterraform-openstack-loadbalancer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thobiast","download_url":"https://codeload.github.com/thobiast/terraform-openstack-loadbalancer/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thobiast%2Fterraform-openstack-loadbalancer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28171353,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2026-01-02T02:00:06.235Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["openstack","terraform","terraform-module"],"created_at":"2026-01-02T08:01:53.854Z","updated_at":"2026-01-02T08:02:22.744Z","avatar_url":"https://github.com/thobiast.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# terraform-openstack-loadbalancer\n\n![Terraform Build](https://github.com/thobiast/terraform-openstack-loadbalancer/workflows/Terraform/badge.svg)\n[![GitHub License](https://img.shields.io/github/license/thobiast/terraform-openstack-loadbalancer)](https://github.com/thobiast/terraform-openstack-loadbalancer/blob/master/LICENSE)\n\nTerraform module to create an OpenStack Load Balancer, including listeners, pools, members, health monitors, and L7 policies/rules.\n\nThis module is designed to be flexible. It accepts structured maps for each resource type, enabling you to define a complete load balancer topology.\n\n## Module versions\n\n- **For Terraform v0.11 and v0.12**, use module version **v0.1.\\***.\n- **Version 2.0+** introduces multiple listeners, more configuration options, and L7 policy support.\n  **This release is not backward compatible.**\n\nIf you are using the older module schema, pin your version to:\n\n```hcl\nversion = \"1.0.0\"\n```\n\n## Usage Example\n\n#### Basic HTTP load balancer\n\n```hcl\n#####################\n### Basic HTTP LB ###\n#####################\nmodule \"openstack-lb\" {\n  source = \"git::https://github.com/thobiast/terraform-openstack-loadbalancer.git\"\n\n  # Logical name for the load balancer\n  lb_name = \"example-basic-http\"\n\n  # Subnet where the LB VIP will be allocated\n  lb_vip_subnet_id = var.subnet_id\n\n  #################\n  # HTTP listener #\n  #################\n  listeners = {\n    # The map key \"my_http\" is the listener key\n    my_http = {\n      protocol      = \"HTTP\"\n      protocol_port = 80\n\n      # default_pool_key MUST match a pool key from the \"pools\" map below\n      # Traffic arriving on this listener will be sent to pool \"my_pool\"\n      default_pool_key = \"my_pool\"\n    }\n  }\n\n  ############\n  # One Pool #\n  ############\n  pools = {\n    # The map key \"my_pool\" is the pool key\n    my_pool = {\n      protocol = \"HTTP\"\n      monitor  = { type = \"HTTP\", delay = 5, timeout = 3, max_retries = 3 }\n\n      # The \"members\" block dynamically adds all backend servers to this pool\n      #\n      #   openstack_compute_instance_v2.http[*]\n      #\n      # Each instance creates one pool member:\n      #   - key           = instance name\n      #   - value         = instance IP\n\t  #   - protocol_port = member port\n      members = {\n        for inst in openstack_compute_instance_v2.http :\n        inst.name =\u003e {\n          address       = inst.network[0].fixed_ip_v4\n          protocol_port = 80\n        }\n      }\n    }\n  }\n}\n```\n\n#### Load balancer with L7 Policy\n\n```hcl\n#########################\n### LB with L7 Policy ###\n#########################\nmodule \"openstack-lb\" {\n  source = \"git::https://github.com/thobiast/terraform-openstack-loadbalancer.git\"\n\n  lb_name          = \"example-l7-policy\"\n  lb_vip_subnet_id = var.subnet_id\n\n  #################\n  # HTTP listener #\n  #################\n  listeners = {\n    # The map key \"my_http_listener\" is the listener key\n    # This same key will be used under `l7policies` to attach L7 policies\n    my_http_listener = {\n      protocol      = \"HTTP\"\n      protocol_port = 80\n      # Must match a pool key from the \"pools\" map below.\n      default_pool_key = \"app_default\"\n    }\n  }\n\n  ###############################\n  # Two pools (default + admin) #\n  ###############################\n  pools = {\n    # The map key \"app_default\" is the pool key\n    # This is the default pool for normal traffic (non-/admin)\n    app_default = {\n      protocol = \"HTTP\"\n      monitor  = { type = \"HTTP\", delay = 5, timeout = 3, max_retries = 3 }\n      members = {\n        # One member per frontend instance\n        for inst in openstack_compute_instance_v2.frontend :\n        inst.name =\u003e {\n          address       = inst.network[0].fixed_ip_v4\n          protocol_port = 80\n        }\n      }\n    }\n    # The map key \"app_admin\" is the pool key\n    # This pool only receives traffic that matches the L7 /admin rule\n    app_admin = {\n      protocol = \"HTTP\"\n      monitor  = { type = \"HTTP\", delay = 5, timeout = 3, max_retries = 3 }\n      members = {\n        # One member per admin instance\n        for inst in openstack_compute_instance_v2.admin :\n        inst.name =\u003e {\n          address       = inst.network[0].fixed_ip_v4\n          protocol_port = 80\n        }\n      }\n    }\n  }\n\n  ################################################################\n  # L7 Policy: redirect /admin* to app_admin pool                #\n  # Example: curl http://\u003cvip\u003e/admin/   # goes to app_admin pool #\n  ################################################################\n  l7policies = {\n    # This map key MUST match the listener key under \"listeners\" map\n    # In this case \"my_http_listener\"\n    my_http_listener = {\n      path_to_admin = {\n        action   = \"REDIRECT_TO_POOL\"\n        position = 1\n        # Redirect to the pool whose key is \"app_admin\" in \"pools\" map\n        redirect_pool_key = \"app_admin\"\n        rules = {\n          path_admin = { type = \"PATH\", compare_type = \"STARTS_WITH\", value = \"/admin\" }\n        }\n      }\n    }\n  }\n}\n```\n\nYou can find additional and more complete examples in the [`examples/`](./examples/) directory.\n\n\u003c!-- BEGIN_TF_DOCS --\u003e\n## Requirements\n\n| Name | Version |\n|------|---------|\n| \u003ca name=\"requirement_terraform\"\u003e\u003c/a\u003e [terraform](#requirement\\_terraform) | \u003e= 1.3.0 |\n| \u003ca name=\"requirement_openstack\"\u003e\u003c/a\u003e [openstack](#requirement\\_openstack) | \u003e= 3.0 |\n\n## Providers\n\n| Name | Version |\n|------|---------|\n| \u003ca name=\"provider_openstack\"\u003e\u003c/a\u003e [openstack](#provider\\_openstack) | \u003e= 3.0 |\n\n## Modules\n\nNo modules.\n\n## Resources\n\n| Name | Type |\n|------|------|\n| [openstack_lb_l7policy_v2.policy](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/lb_l7policy_v2) | resource |\n| [openstack_lb_l7rule_v2.rule](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/lb_l7rule_v2) | resource |\n| [openstack_lb_listener_v2.listener](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/lb_listener_v2) | resource |\n| [openstack_lb_loadbalancer_v2.loadbalancer](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/lb_loadbalancer_v2) | resource |\n| [openstack_lb_member_v2.member](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/lb_member_v2) | resource |\n| [openstack_lb_monitor_v2.monitor](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/lb_monitor_v2) | resource |\n| [openstack_lb_pool_v2.pool](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/lb_pool_v2) | resource |\n\n## Inputs\n\n| Name | Description | Type | Default | Required |\n|------|-------------|------|---------|:--------:|\n| \u003ca name=\"input_admin_state_up\"\u003e\u003c/a\u003e [admin\\_state\\_up](#input\\_admin\\_state\\_up) | Load balancer admin state | `bool` | `true` | no |\n| \u003ca name=\"input_l7policies\"\u003e\u003c/a\u003e [l7policies](#input\\_l7policies) | Map of listener-key =\u003e map of L7 policies. Policies can redirect to URL or to a pool (by pool key).\u003cbr/\u003e- The listener\\_key must match a key from var.listeners map.\u003cbr/\u003e- The policy\\_key is a logical identifier for the policy (e.g., redirect-rule).\u003cbr/\u003e- redirect\\_pool\\_key (optional) must reference a valid key from var.pools map.\u003cbr/\u003e- Each policy can contain a nested map of rules, where each key is a logical identifier for the rule. | \u003cpre\u003emap(map(object({\u003cbr/\u003e    name               = optional(string)\u003cbr/\u003e    description        = optional(string)\u003cbr/\u003e    action             = string\u003cbr/\u003e    position           = number\u003cbr/\u003e    redirect_url       = optional(string)\u003cbr/\u003e    redirect_pool_key  = optional(string)\u003cbr/\u003e    redirect_prefix    = optional(string)\u003cbr/\u003e    redirect_http_code = optional(number)\u003cbr/\u003e    admin_state_up     = optional(bool, true)\u003cbr/\u003e\u003cbr/\u003e    rules = optional(map(object({\u003cbr/\u003e      type           = string\u003cbr/\u003e      compare_type   = string\u003cbr/\u003e      value          = string\u003cbr/\u003e      key            = optional(string)\u003cbr/\u003e      invert         = optional(bool, false)\u003cbr/\u003e      admin_state_up = optional(bool, true)\u003cbr/\u003e    })), {})\u003cbr/\u003e  })))\u003c/pre\u003e | `{}` | no |\n| \u003ca name=\"input_lb_availability_zone\"\u003e\u003c/a\u003e [lb\\_availability\\_zone](#input\\_lb\\_availability\\_zone) | The availability zone of the load balancer | `string` | `null` | no |\n| \u003ca name=\"input_lb_description\"\u003e\u003c/a\u003e [lb\\_description](#input\\_lb\\_description) | Human-readable description for the load balancer | `string` | `\"\"` | no |\n| \u003ca name=\"input_lb_flavor_id\"\u003e\u003c/a\u003e [lb\\_flavor\\_id](#input\\_lb\\_flavor\\_id) | Load balancer flavor (HA, stand-alone) | `string` | `null` | no |\n| \u003ca name=\"input_lb_loadbalancer_provider\"\u003e\u003c/a\u003e [lb\\_loadbalancer\\_provider](#input\\_lb\\_loadbalancer\\_provider) | The Octavia provider driver name | `string` | `null` | no |\n| \u003ca name=\"input_lb_name\"\u003e\u003c/a\u003e [lb\\_name](#input\\_lb\\_name) | Human-readable name for the load balancer | `string` | n/a | yes |\n| \u003ca name=\"input_lb_vip_address\"\u003e\u003c/a\u003e [lb\\_vip\\_address](#input\\_lb\\_vip\\_address) | The fixed VIP IP address of the load balancer | `string` | `null` | no |\n| \u003ca name=\"input_lb_vip_network_id\"\u003e\u003c/a\u003e [lb\\_vip\\_network\\_id](#input\\_lb\\_vip\\_network\\_id) | The network on which to allocate the load balancer's address | `string` | `null` | no |\n| \u003ca name=\"input_lb_vip_port_id\"\u003e\u003c/a\u003e [lb\\_vip\\_port\\_id](#input\\_lb\\_vip\\_port\\_id) | The network's port on which want to connect the loadbalancer | `string` | `null` | no |\n| \u003ca name=\"input_lb_vip_qos_policy_id\"\u003e\u003c/a\u003e [lb\\_vip\\_qos\\_policy\\_id](#input\\_lb\\_vip\\_qos\\_policy\\_id) | The ID of the QoS Policy which will be applied to the VIP port | `string` | `null` | no |\n| \u003ca name=\"input_lb_vip_subnet_id\"\u003e\u003c/a\u003e [lb\\_vip\\_subnet\\_id](#input\\_lb\\_vip\\_subnet\\_id) | The network's subnet on which to allocate the load balancer's address | `string` | `null` | no |\n| \u003ca name=\"input_listeners\"\u003e\u003c/a\u003e [listeners](#input\\_listeners) | Map of listeners to create, keyed by a logical listener name\u003cbr/\u003e- default\\_pool\\_key (optional) must reference a key in var.pools map | \u003cpre\u003emap(object({\u003cbr/\u003e    name                        = optional(string)\u003cbr/\u003e    description                 = optional(string)\u003cbr/\u003e    protocol                    = string\u003cbr/\u003e    protocol_port               = number\u003cbr/\u003e    connection_limit            = optional(number)\u003cbr/\u003e    timeout_client_data         = optional(number)\u003cbr/\u003e    timeout_member_connect      = optional(number)\u003cbr/\u003e    timeout_member_data         = optional(number)\u003cbr/\u003e    timeout_tcp_inspect         = optional(number)\u003cbr/\u003e    default_tls_container_ref   = optional(string)\u003cbr/\u003e    sni_container_refs          = optional(list(string), [])\u003cbr/\u003e    insert_headers              = optional(map(string), {})\u003cbr/\u003e    allowed_cidrs               = optional(list(string), [])\u003cbr/\u003e    client_authentication       = optional(string)\u003cbr/\u003e    client_ca_tls_container_ref = optional(string)\u003cbr/\u003e    client_crl_container_ref    = optional(string)\u003cbr/\u003e    tls_ciphers                 = optional(string)\u003cbr/\u003e    tls_versions                = optional(list(string), [])\u003cbr/\u003e    tags                        = optional(list(string), [])\u003cbr/\u003e    default_pool_key            = optional(string)\u003cbr/\u003e    admin_state_up              = optional(bool, true)\u003cbr/\u003e  }))\u003c/pre\u003e | `{}` | no |\n| \u003ca name=\"input_pools\"\u003e\u003c/a\u003e [pools](#input\\_pools) | Map of pools keyed where each key represents a unique pool name\u003cbr/\u003e- Each pool may define session\\_persistence, an optional monitor, and a map of members.\u003cbr/\u003e- The members map keys are logical identifiers for each member. | \u003cpre\u003emap(object({\u003cbr/\u003e    name        = optional(string)\u003cbr/\u003e    description = optional(string)\u003cbr/\u003e    protocol    = string\u003cbr/\u003e    lb_method   = optional(string, \"ROUND_ROBIN\")\u003cbr/\u003e\u003cbr/\u003e    persistence = optional(object({\u003cbr/\u003e      type        = string\u003cbr/\u003e      cookie_name = optional(string)\u003cbr/\u003e    }))\u003cbr/\u003e\u003cbr/\u003e    monitor = optional(object({\u003cbr/\u003e      name             = optional(string)\u003cbr/\u003e      type             = string\u003cbr/\u003e      delay            = number\u003cbr/\u003e      timeout          = number\u003cbr/\u003e      max_retries      = number\u003cbr/\u003e      max_retries_down = optional(number)\u003cbr/\u003e      url_path         = optional(string)\u003cbr/\u003e      http_method      = optional(string)\u003cbr/\u003e      http_version     = optional(string)\u003cbr/\u003e      expected_codes   = optional(string)\u003cbr/\u003e      admin_state_up   = optional(bool, true)\u003cbr/\u003e    }))\u003cbr/\u003e\u003cbr/\u003e    members = optional(map(object({\u003cbr/\u003e      name            = optional(string)\u003cbr/\u003e      address         = string\u003cbr/\u003e      protocol_port   = number\u003cbr/\u003e      subnet_id       = optional(string)\u003cbr/\u003e      weight          = optional(number)\u003cbr/\u003e      monitor_port    = optional(number)\u003cbr/\u003e      monitor_address = optional(string)\u003cbr/\u003e      backup          = optional(bool)\u003cbr/\u003e      tags            = optional(list(string), [])\u003cbr/\u003e    })), {})\u003cbr/\u003e  }))\u003c/pre\u003e | `{}` | no |\n| \u003ca name=\"input_tags\"\u003e\u003c/a\u003e [tags](#input\\_tags) | A list of strings to add to the load balancer | `list(string)` | `[]` | no |\n\n## Outputs\n\n| Name | Description |\n|------|-------------|\n| \u003ca name=\"output_l7policies\"\u003e\u003c/a\u003e [l7policies](#output\\_l7policies) | A map of all created OpenStack L7 policy resource objects |\n| \u003ca name=\"output_l7policy_ids_by_key\"\u003e\u003c/a\u003e [l7policy\\_ids\\_by\\_key](#output\\_l7policy\\_ids\\_by\\_key) | Map: listener/policy - l7policy ID |\n| \u003ca name=\"output_l7rule_ids_by_key\"\u003e\u003c/a\u003e [l7rule\\_ids\\_by\\_key](#output\\_l7rule\\_ids\\_by\\_key) | Map: listener/policy/rule - l7rule ID |\n| \u003ca name=\"output_l7rules\"\u003e\u003c/a\u003e [l7rules](#output\\_l7rules) | A map of all created OpenStack L7 rule resource objects |\n| \u003ca name=\"output_listener_ids_by_key\"\u003e\u003c/a\u003e [listener\\_ids\\_by\\_key](#output\\_listener\\_ids\\_by\\_key) | Map: listener key - listener ID |\n| \u003ca name=\"output_listeners\"\u003e\u003c/a\u003e [listeners](#output\\_listeners) | A map of all created OpenStack listener resource objects |\n| \u003ca name=\"output_loadbalancer\"\u003e\u003c/a\u003e [loadbalancer](#output\\_loadbalancer) | The full OpenStack load balancer resource object |\n| \u003ca name=\"output_loadbalancer_id\"\u003e\u003c/a\u003e [loadbalancer\\_id](#output\\_loadbalancer\\_id) | Load balancer ID |\n| \u003ca name=\"output_member_ids\"\u003e\u003c/a\u003e [member\\_ids](#output\\_member\\_ids) | Map: pool/member - member ID |\n| \u003ca name=\"output_members\"\u003e\u003c/a\u003e [members](#output\\_members) | A map of all created OpenStack member resource objects |\n| \u003ca name=\"output_monitor_ids_by_pool_key\"\u003e\u003c/a\u003e [monitor\\_ids\\_by\\_pool\\_key](#output\\_monitor\\_ids\\_by\\_pool\\_key) | Map: pool key - monitor ID |\n| \u003ca name=\"output_monitors\"\u003e\u003c/a\u003e [monitors](#output\\_monitors) | A map of all created OpenStack monitor resource objects |\n| \u003ca name=\"output_pool_ids_by_key\"\u003e\u003c/a\u003e [pool\\_ids\\_by\\_key](#output\\_pool\\_ids\\_by\\_key) | Map: pool key - pool ID |\n| \u003ca name=\"output_pools\"\u003e\u003c/a\u003e [pools](#output\\_pools) | A map of all created OpenStack pool resource objects |\n| \u003ca name=\"output_vip_address\"\u003e\u003c/a\u003e [vip\\_address](#output\\_vip\\_address) | Allocated VIP address |\n\u003c!-- END_TF_DOCS --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthobiast%2Fterraform-openstack-loadbalancer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthobiast%2Fterraform-openstack-loadbalancer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthobiast%2Fterraform-openstack-loadbalancer/lists"}