Skip to content

Commit 84eca8a

Browse files
authored
Merge pull request #2472 from tc80/tc80/lors
2 parents 1839713 + 4c0c588 commit 84eca8a

7 files changed

+127
-15
lines changed

.changelog/2472.txt

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
```release-note:enhancement
2+
resource/cloudflare_load_balancer: Add support for least_outstanding_requests steering
3+
```
4+
5+
```release-note:enhancement
6+
resource/cloudflare_load_balancer_pool: Add support for least_outstanding_requests origin steering
7+
```

docs/resources/load_balancer.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,13 @@ resource "cloudflare_load_balancer_pool" "example" {
8888
- `location_strategy` (Block Set) Controls location-based steering for non-proxied requests. (see [below for nested schema](#nestedblock--location_strategy))
8989
- `pop_pools` (Block Set) A set containing mappings of Cloudflare Point-of-Presence (PoP) identifiers to a list of pool IDs (ordered by their failover priority) for the PoP (datacenter). This feature is only available to enterprise customers. (see [below for nested schema](#nestedblock--pop_pools))
9090
- `proxied` (Boolean) Whether the hostname gets Cloudflare's origin protection. Defaults to `false`. Conflicts with `ttl`.
91-
- `random_steering` (Block Set) Configures pool weights for random steering. When the [`steering_policy="random"`](#steering_policy), a random pool is selected with probability proportional to these pool weights. (see [below for nested schema](#nestedblock--random_steering))
91+
- `random_steering` (Block Set) Configures pool weights. When [`steering_policy="random"`](#steering_policy), a random pool is selected with probability proportional to pool weights. When [`steering_policy="least_outstanding_requests"`](#steering_policy), pool weights are used to scale each pool's outstanding requests. (see [below for nested schema](#nestedblock--random_steering))
9292
- `region_pools` (Block Set) A set containing mappings of region codes to a list of pool IDs (ordered by their failover priority) for the given region. (see [below for nested schema](#nestedblock--region_pools))
9393
- `rules` (Block List) A list of rules for this load balancer to execute. (see [below for nested schema](#nestedblock--rules))
9494
- `session_affinity` (String) Specifies the type of session affinity the load balancer should use unless specified as `none` or `""` (default). With value `cookie`, on the first request to a proxied load balancer, a cookie is generated, encoding information of which origin the request will be forwarded to. Subsequent requests, by the same client to the same load balancer, will be sent to the origin server the cookie encodes, for the duration of the cookie and as long as the origin server remains healthy. If the cookie has expired or the origin server is unhealthy then a new origin server is calculated and used. Value `ip_cookie` behaves the same as `cookie` except the initial origin selection is stable and based on the client's IP address. Available values: `""`, `none`, `cookie`, `ip_cookie`. Defaults to `none`.
9595
- `session_affinity_attributes` (Block Set) Configure cookie attributes for session affinity cookie. (see [below for nested schema](#nestedblock--session_affinity_attributes))
9696
- `session_affinity_ttl` (Number) Time, in seconds, until this load balancer's session affinity cookie expires after being created. This parameter is ignored unless a supported session affinity policy is set. The current default of `82800` (23 hours) will be used unless [`session_affinity_ttl`](#session_affinity_ttl) is explicitly set. Once the expiry time has been reached, subsequent requests may get sent to a different origin server. Valid values are between `1800` and `604800`.
97-
- `steering_policy` (String) The method the load balancer uses to determine the route to your origin. Value `off` uses [`default_pool_ids`](#default_pool_ids). Value `geo` uses [`pop_pools`](#pop_pools)/[`country_pools`](#country_pools)/[`region_pools`](#region_pools). For non-proxied requests, the [`country`](#country) for [`country_pools`](#country_pools) is determined by [`location_strategy`](#location_strategy). Value `random` selects a pool randomly. Value `dynamic_latency` uses round trip time to select the closest pool in [`default_pool_ids`](#default_pool_ids) (requires pool health checks). Value `proximity` uses the pools' latitude and longitude to select the closest pool using the Cloudflare PoP location for proxied requests or the location determined by [`location_strategy`](#location_strategy) for non-proxied requests. Value `""` maps to `geo` if you use [`pop_pools`](#pop_pools)/[`country_pools`](#country_pools)/[`region_pools`](#region_pools) otherwise `off`. Available values: `off`, `geo`, `dynamic_latency`, `random`, `proximity`, `""` Defaults to `""`.
97+
- `steering_policy` (String) The method the load balancer uses to determine the route to your origin. Value `off` uses [`default_pool_ids`](#default_pool_ids). Value `geo` uses [`pop_pools`](#pop_pools)/[`country_pools`](#country_pools)/[`region_pools`](#region_pools). For non-proxied requests, the [`country`](#country) for [`country_pools`](#country_pools) is determined by [`location_strategy`](#location_strategy). Value `random` selects a pool randomly. Value `dynamic_latency` uses round trip time to select the closest pool in [`default_pool_ids`](#default_pool_ids) (requires pool health checks). Value `proximity` uses the pools' latitude and longitude to select the closest pool using the Cloudflare PoP location for proxied requests or the location determined by [`location_strategy`](#location_strategy) for non-proxied requests. Value `least_outstanding_requests` selects a pool by taking into consideration [`random_steering`](#random_steering) weights, as well as each pool's number of outstanding requests. Pools with more pending requests are weighted proportionately less relative to others. Value `""` maps to `geo` if you use [`pop_pools`](#pop_pools)/[`country_pools`](#country_pools)/[`region_pools`](#region_pools) otherwise `off`. Available values: `off`, `geo`, `dynamic_latency`, `random`, `proximity`, `least_outstanding_requests`, `""` Defaults to `""`.
9898
- `ttl` (Number) Time to live (TTL) of the DNS entry for the IP address returned by this load balancer. This cannot be set for proxied load balancers. Defaults to `30`. Conflicts with `proxied`.
9999

100100
### Read-Only
@@ -194,12 +194,12 @@ Optional:
194194
- `fallback_pool` (String) The pool ID to use when all other pools are detected as unhealthy.
195195
- `location_strategy` (Block Set) Controls location-based steering for non-proxied requests. (see [below for nested schema](#nestedblock--rules--overrides--location_strategy))
196196
- `pop_pools` (Block Set) A set containing mappings of Cloudflare Point-of-Presence (PoP) identifiers to a list of pool IDs (ordered by their failover priority) for the PoP (datacenter). This feature is only available to enterprise customers. (see [below for nested schema](#nestedblock--rules--overrides--pop_pools))
197-
- `random_steering` (Block Set) Configures pool weights for random steering. When the [`steering_policy="random"`](#steering_policy), a random pool is selected with probability proportional to these pool weights. (see [below for nested schema](#nestedblock--rules--overrides--random_steering))
197+
- `random_steering` (Block Set) Configures pool weights. When [`steering_policy="random"`](#steering_policy), a random pool is selected with probability proportional to pool weights. When [`steering_policy="least_outstanding_requests"`](#steering_policy), pool weights are used to scale each pool's outstanding requests. (see [below for nested schema](#nestedblock--rules--overrides--random_steering))
198198
- `region_pools` (Block Set) A set containing mappings of region codes to a list of pool IDs (ordered by their failover priority) for the given region. (see [below for nested schema](#nestedblock--rules--overrides--region_pools))
199199
- `session_affinity` (String) Configure cookie attributes for session affinity cookie.
200200
- `session_affinity_attributes` (Block Set) Configure cookie attributes for session affinity cookie. Note that the property [`drain_duration`](#drain_duration) is not currently supported as a rule override. (see [below for nested schema](#nestedblock--rules--overrides--session_affinity_attributes))
201201
- `session_affinity_ttl` (Number) Time, in seconds, until this load balancer's session affinity cookie expires after being created. This parameter is ignored unless a supported session affinity policy is set. The current default of `82800` (23 hours) will be used unless [`session_affinity_ttl`](#session_affinity_ttl) is explicitly set. Once the expiry time has been reached, subsequent requests may get sent to a different origin server. Valid values are between `1800` and `604800`.
202-
- `steering_policy` (String) The method the load balancer uses to determine the route to your origin. Value `off` uses [`default_pool_ids`](#default_pool_ids). Value `geo` uses [`pop_pools`](#pop_pools)/[`country_pools`](#country_pools)/[`region_pools`](#region_pools). For non-proxied requests, the [`country`](#country) for [`country_pools`](#country_pools) is determined by [`location_strategy`](#location_strategy). Value `random` selects a pool randomly. Value `dynamic_latency` uses round trip time to select the closest pool in [`default_pool_ids`](#default_pool_ids) (requires pool health checks). Value `proximity` uses the pools' latitude and longitude to select the closest pool using the Cloudflare PoP location for proxied requests or the location determined by [`location_strategy`](#location_strategy) for non-proxied requests. Value `""` maps to `geo` if you use [`pop_pools`](#pop_pools)/[`country_pools`](#country_pools)/[`region_pools`](#region_pools) otherwise `off`. Available values: `off`, `geo`, `dynamic_latency`, `random`, `proximity`, `""` Defaults to `""`.
202+
- `steering_policy` (String) The method the load balancer uses to determine the route to your origin. Value `off` uses [`default_pool_ids`](#default_pool_ids). Value `geo` uses [`pop_pools`](#pop_pools)/[`country_pools`](#country_pools)/[`region_pools`](#region_pools). For non-proxied requests, the [`country`](#country) for [`country_pools`](#country_pools) is determined by [`location_strategy`](#location_strategy). Value `random` selects a pool randomly. Value `dynamic_latency` uses round trip time to select the closest pool in [`default_pool_ids`](#default_pool_ids) (requires pool health checks). Value `proximity` uses the pools' latitude and longitude to select the closest pool using the Cloudflare PoP location for proxied requests or the location determined by [`location_strategy`](#location_strategy) for non-proxied requests. Value `least_outstanding_requests` selects a pool by taking into consideration [`random_steering`](#random_steering) weights, as well as each pool's number of outstanding requests. Pools with more pending requests are weighted proportionately less relative to others. Value `""` maps to `geo` if you use [`pop_pools`](#pop_pools)/[`country_pools`](#country_pools)/[`region_pools`](#region_pools) otherwise `off`. Available values: `off`, `geo`, `dynamic_latency`, `random`, `proximity`, `least_outstanding_requests`, `""` Defaults to `""`.
203203
- `ttl` (Number) Time to live (TTL) of the DNS entry for the IP address returned by this load balancer. This cannot be set for proxied load balancers. Defaults to `30`.
204204

205205
<a id="nestedblock--rules--overrides--adaptive_routing"></a>

docs/resources/load_balancer_pool.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ Optional:
9191

9292
- `enabled` (Boolean) Whether this origin is enabled. Disabled origins will not receive traffic and are excluded from health checks. Defaults to `true`.
9393
- `header` (Block Set) HTTP request headers. (see [below for nested schema](#nestedblock--origins--header))
94-
- `weight` (Number) The weight (0.01 - 1.00) of this origin, relative to other origins in the pool. Equal values mean equal weighting. A weight of 0 means traffic will not be sent to this origin, but health is still checked. Defaults to `1`.
94+
- `weight` (Number) The weight (0.01 - 1.00) of this origin, relative to other origins in the pool. Equal values mean equal weighting. A weight of 0 means traffic will not be sent to this origin, but health is still checked. When [`origin_steering.policy="least_outstanding_requests"`](#policy), weight is used to scale the origin's outstanding requests. Defaults to `1`.
9595

9696
<a id="nestedblock--origins--header"></a>
9797
### Nested Schema for `origins.header`
@@ -119,7 +119,7 @@ Optional:
119119

120120
Optional:
121121

122-
- `policy` (String) Origin steering policy to be used. Available values: `""`, `hash`, `random`. Defaults to `random`.
122+
- `policy` (String) Origin steering policy to be used. Value `random` selects an origin randomly. Value `hash` selects an origin by computing a hash over the CF-Connecting-IP address. Value `least_outstanding_requests` selects an origin by taking into consideration origin weights, as well as each origin's number of outstanding requests. Origins with more pending requests are weighted proportionately less relative to others. Available values: `""`, `hash`, `random`, `least_outstanding_requests`. Defaults to `random`.
123123

124124
## Import
125125

internal/sdkv2provider/resource_cloudflare_load_balancer_pool_test.go

+52
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,40 @@ func TestAccCloudflareLoadBalancerPool_Basic(t *testing.T) {
8484
})
8585
}
8686

87+
func TestAccCloudflareLoadBalancerPool_OriginSteeringLeastOutstandingRequests(t *testing.T) {
88+
// multiple instances of this config would conflict but we only use it once
89+
t.Parallel()
90+
testStartTime := time.Now().UTC()
91+
var loadBalancerPool cloudflare.LoadBalancerPool
92+
rnd := generateRandomResourceName()
93+
name := "cloudflare_load_balancer_pool." + rnd
94+
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
95+
96+
resource.Test(t, resource.TestCase{
97+
PreCheck: func() { testAccPreCheck(t) },
98+
ProviderFactories: providerFactories,
99+
CheckDestroy: testAccCheckCloudflareLoadBalancerPoolDestroy,
100+
Steps: []resource.TestStep{
101+
{
102+
Config: testAccCheckCloudflareLoadBalancerPoolConfigOriginSteeringLeastOutstandingRequests(rnd, accountID),
103+
Check: resource.ComposeTestCheckFunc(
104+
testAccCheckCloudflareLoadBalancerPoolExists(name, &loadBalancerPool),
105+
// dont check that specified values are set, this will be evident by lack of plan diff
106+
// some values will get empty values
107+
resource.TestCheckResourceAttr(name, "check_regions.#", "0"),
108+
resource.TestCheckResourceAttr(name, "header.#", "0"),
109+
resource.TestCheckResourceAttr(name, "origin_steering.#", "1"),
110+
resource.TestCheckTypeSetElemNestedAttrs(name, "origin_steering.*", map[string]string{
111+
"policy": "least_outstanding_requests",
112+
}),
113+
// also expect api to generate some values
114+
testAccCheckCloudflareLoadBalancerPoolDates(name, &loadBalancerPool, testStartTime),
115+
),
116+
},
117+
},
118+
})
119+
}
120+
87121
func TestAccCloudflareLoadBalancerPool_FullySpecified(t *testing.T) {
88122
t.Parallel()
89123
var loadBalancerPool cloudflare.LoadBalancerPool
@@ -269,6 +303,24 @@ resource "cloudflare_load_balancer_pool" "%[1]s" {
269303
}`, id, accountID)
270304
}
271305

306+
func testAccCheckCloudflareLoadBalancerPoolConfigOriginSteeringLeastOutstandingRequests(id, accountID string) string {
307+
return fmt.Sprintf(`
308+
resource "cloudflare_load_balancer_pool" "%[1]s" {
309+
account_id = "%[2]s"
310+
name = "my-tf-pool-basic-%[1]s"
311+
latitude = 12.3
312+
longitude = 55
313+
origins {
314+
name = "example-1"
315+
address = "192.0.2.1"
316+
enabled = true
317+
}
318+
origin_steering {
319+
policy = "least_outstanding_requests"
320+
}
321+
}`, id, accountID)
322+
}
323+
272324
func testAccCheckCloudflareLoadBalancerPoolConfigFullySpecified(id, headerValue, accountID string) string {
273325
return fmt.Sprintf(`
274326
resource "cloudflare_load_balancer_pool" "%[1]s" {

internal/sdkv2provider/resource_cloudflare_load_balancer_test.go

+53
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,39 @@ func TestAccCloudflareLoadBalancer_ProximityBalanced(t *testing.T) {
334334
})
335335
}
336336

337+
func TestAccCloudflareLoadBalancer_LeastOutstandingRequestsBalanced(t *testing.T) {
338+
t.Parallel()
339+
var loadBalancer cloudflare.LoadBalancer
340+
zone := os.Getenv("CLOUDFLARE_DOMAIN")
341+
zoneID := os.Getenv("CLOUDFLARE_ZONE_ID")
342+
rnd := generateRandomResourceName()
343+
name := "cloudflare_load_balancer." + rnd
344+
345+
resource.Test(t, resource.TestCase{
346+
PreCheck: func() { testAccPreCheck(t) },
347+
ProviderFactories: providerFactories,
348+
CheckDestroy: testAccCheckCloudflareLoadBalancerDestroy,
349+
Steps: []resource.TestStep{
350+
{
351+
Config: testAccCheckCloudflareLoadBalancerConfigLeastOutstandingRequestsBalanced(zoneID, zone, rnd),
352+
Check: resource.ComposeTestCheckFunc(
353+
testAccCheckCloudflareLoadBalancerExists(name, &loadBalancer),
354+
testAccCheckCloudflareLoadBalancerIDIsValid(name, zoneID),
355+
// checking our overrides of default values worked
356+
resource.TestCheckResourceAttr(name, "description", "tf-acctest load balancer using least outstanding requests steering"),
357+
resource.TestCheckResourceAttr(name, "proxied", "true"),
358+
resource.TestCheckResourceAttr(name, "ttl", "0"),
359+
resource.TestCheckResourceAttr(name, "steering_policy", "least_outstanding_requests"),
360+
resource.TestCheckResourceAttr(name, "rules.0.name", "test rule 1"),
361+
resource.TestCheckResourceAttr(name, "rules.0.condition", "dns.qry.type == 28"),
362+
resource.TestCheckResourceAttr(name, "rules.0.overrides.#", "1"),
363+
resource.TestCheckResourceAttr(name, "rules.0.overrides.0.steering_policy", "least_outstanding_requests"),
364+
),
365+
},
366+
},
367+
})
368+
}
369+
337370
func TestAccCloudflareLoadBalancer_Rules(t *testing.T) {
338371
t.Parallel()
339372
var loadBalancer cloudflare.LoadBalancer
@@ -719,6 +752,26 @@ resource "cloudflare_load_balancer" "%[3]s" {
719752
}`, zoneID, zone, id)
720753
}
721754

755+
func testAccCheckCloudflareLoadBalancerConfigLeastOutstandingRequestsBalanced(zoneID, zone, id string) string {
756+
return testAccCheckCloudflareLoadBalancerPoolConfigBasic(id, accountID) + fmt.Sprintf(`
757+
resource "cloudflare_load_balancer" "%[3]s" {
758+
zone_id = "%[1]s"
759+
name = "tf-testacc-lb-%[3]s.%[2]s"
760+
fallback_pool_id = "${cloudflare_load_balancer_pool.%[3]s.id}"
761+
default_pool_ids = ["${cloudflare_load_balancer_pool.%[3]s.id}"]
762+
description = "tf-acctest load balancer using least outstanding requests steering"
763+
proxied = true
764+
steering_policy = "least_outstanding_requests"
765+
rules {
766+
name = "test rule 1"
767+
condition = "dns.qry.type == 28"
768+
overrides {
769+
steering_policy = "least_outstanding_requests"
770+
}
771+
}
772+
}`, zoneID, zone, id)
773+
}
774+
722775
func testAccCheckCloudflareLoadBalancerConfigDuplicatePool(zoneID, zone, id string) string {
723776
return testAccCheckCloudflareLoadBalancerPoolConfigBasic(id, accountID) + fmt.Sprintf(`
724777
resource "cloudflare_load_balancer" "%[3]s" {

0 commit comments

Comments
 (0)