Skip to content

Commit 5c63523

Browse files
authored
feat(lb): add private network resource (#3153)
- add tests - add docs and cassettes - manage PN attachments externally - use zone from returned LB response - add checks
1 parent 948d2f1 commit 5c63523

File tree

15 files changed

+5057
-2740
lines changed

15 files changed

+5057
-2740
lines changed

docs/resources/lb.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ The following arguments are supported:
109109
- `private_network_id` - (Required) The ID of the Private Network to attach to.
110110
- ~> **Important:** Updates to `private_network` will recreate the attachment.
111111
- `ipam_ids` - (Optional) IPAM ID of a pre-reserved IP address to assign to the Load Balancer on this Private Network.
112+
- `external_private_networks` - (Defaults to `false`) A boolean to specify whether to use [lb_private_network](../resources/lb_private_network.md).
113+
If `external_private_networks` is set to `true`, `private_network` can not be set directly in the Load Balancer.
112114
- `ssl_compatibility_level` - (Optional) Enforces minimal SSL version (in SSL/TLS offloading context). Please check [possible values](https://www.scaleway.com/en/developers/api/load-balancer/zoned-api/#path-load-balancer-create-a-load-balancer).
113115
- `zone` - (Defaults to [provider](../index.md#zone) `zone`) The [zone](../guides/regions_and_zones.md#zones) of the Load Balancer.
114116
- `project_id` - (Defaults to [provider](../index.md#project_id) `project_id`) The ID of the Project the Load Balancer is associated with.
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
---
2+
subcategory: "Load Balancers"
3+
page_title: "Scaleway: scaleway_lb_private_network"
4+
---
5+
6+
# Resource: scaleway_lb_private_network
7+
8+
Creates and manages Scaleway Load Balancer Private Network attachments.
9+
10+
For more information, see the [main documentation](https://www.scaleway.com/en/docs/load-balancer/how-to/use-with-private-network/).
11+
12+
## Example Usage
13+
14+
### Basic
15+
16+
```terraform
17+
resource "scaleway_vpc" "vpc01" {
18+
name = "my vpc"
19+
}
20+
21+
resource "scaleway_vpc_private_network" "pn01" {
22+
vpc_id = scaleway_vpc.vpc01.id
23+
ipv4_subnet {
24+
subnet = "172.16.32.0/22"
25+
}
26+
}
27+
28+
resource "scaleway_ipam_ip" "ip01" {
29+
address = "172.16.32.7"
30+
source {
31+
private_network_id = scaleway_vpc_private_network.pn01.id
32+
}
33+
}
34+
35+
resource "scaleway_lb" "lb01" {
36+
name = "test-lb-private-network"
37+
type = "LB-S"
38+
}
39+
40+
resource "scaleway_lb_private_network" "lbpn01" {
41+
lb_id = scaleway_lb.lb01.id
42+
private_network_id = scaleway_vpc_private_network.pn01.id
43+
ipam_ip_ids = [scaleway_ipam_ip.ip01.id]
44+
}
45+
```
46+
47+
## Argument Reference
48+
49+
The following arguments are supported:
50+
51+
- `zone` - (Defaults to [provider](../index.md#zone) `zone`) The [zone](../guides/regions_and_zones.md#zones) in which the Private Network should be attached.
52+
- `project_id` - (Defaults to [provider](../index.md#project_id) `project_id`) The ID of the Project the Private Network attachment is associated with.
53+
- `lb_id` - (Required) The load-balancer ID to attach the private network to.
54+
- `private_network_id` - (Required) The private network ID to attach.
55+
- `ipam_ip_ids` - (Required) The IPAM ID of a pre-reserved IP address to assign to the Load Balancer on this Private Network.
56+
57+
## Attributes Reference
58+
59+
In addition to all arguments above, the following attributes are exported:
60+
61+
- `id` - The ID of the Private Network attachment, which is of the form `{zone}/{lb-id}/{private-network-id}` e.g. `fr-par-1/11111111-1111-1111-1111-111111111111/11111111-1111-1111-1111-111111111111`
62+
- `status` - The status of the Private Network attachment.
63+
- `created_at` - The date and time of the creation of the Private Network attachment (RFC 3339 format).
64+
- `updated_at` - The date and time of the last update of the Private Network attachment (RFC 3339 format).
65+
66+
## Import
67+
68+
Private Network attachments can be imported using `{zone}/{lb-id}/{private-network-id}`, e.g.
69+
70+
```bash
71+
terraform import scaleway_lb_private_network.lbpn01 fr-par-1/11111111-1111-1111-1111-111111111111/11111111-1111-1111-1111-111111111111
72+
```

internal/services/baremetal/testdata/server-with-ipam-private-network.cassette.yaml

Lines changed: 1690 additions & 1837 deletions
Large diffs are not rendered by default.

internal/services/lb/helpers_lb.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,12 @@ func customizeDiffAssignFlexibleIPv6(_ context.Context, diff *schema.ResourceDif
226226

227227
return nil
228228
}
229+
230+
func ResourceLBPrivateNetworkParseID(resourceID string) (zone scw.Zone, lbID string, pnID string, err error) {
231+
idParts := strings.Split(resourceID, "/")
232+
if len(idParts) != 3 {
233+
return "", "", "", fmt.Errorf("can't parse user resource id: %s", resourceID)
234+
}
235+
236+
return scw.Zone(idParts[0]), idParts[1], idParts[2], nil
237+
}

internal/services/lb/lb.go

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,13 @@ func ResourceLb() *schema.Resource {
107107
Deprecated: "The resource ip will be destroyed by it's own resource. Please set this to `false`",
108108
},
109109
"private_network": {
110-
Type: schema.TypeSet,
111-
Optional: true,
112-
MaxItems: 8,
113-
Set: lbPrivateNetworkSetHash,
114-
Description: "List of private network to connect with your load balancer",
110+
Type: schema.TypeSet,
111+
Optional: true,
112+
Computed: true,
113+
MaxItems: 8,
114+
Set: lbPrivateNetworkSetHash,
115+
ConflictsWith: []string{"external_private_networks"},
116+
Description: "List of private network to connect with your load balancer",
115117
DiffSuppressFunc: func(k, oldValue, newValue string, _ *schema.ResourceData) bool {
116118
// Check if the key is for the 'private_network_id' attribute
117119
if strings.HasSuffix(k, "private_network_id") {
@@ -168,6 +170,13 @@ func ResourceLb() *schema.Resource {
168170
},
169171
},
170172
},
173+
"external_private_networks": {
174+
Type: schema.TypeBool,
175+
Optional: true,
176+
Default: false,
177+
Description: "This boolean determines if private network attachments should be managed externally through the `scaleway_lb_private_network` resource. When set, `private_network` must not be configured in this resource",
178+
ConflictsWith: []string{"private_network"},
179+
},
171180
"ssl_compatibility_level": {
172181
Type: schema.TypeString,
173182
Optional: true,
@@ -265,22 +274,24 @@ func resourceLbCreate(ctx context.Context, d *schema.ResourceData, m any) diag.D
265274
return diag.FromErr(err)
266275
}
267276

268-
// attach private network
269-
pnConfigs, pnExist := d.GetOk("private_network")
270-
if pnExist {
271-
pnConfigs, err := expandPrivateNetworks(pnConfigs)
272-
if err != nil {
273-
return diag.FromErr(err)
274-
}
277+
if !d.Get("external_private_networks").(bool) {
278+
// attach private network
279+
pnConfigs, pnExist := d.GetOk("private_network")
280+
if pnExist {
281+
pnConfigs, err := expandPrivateNetworks(pnConfigs)
282+
if err != nil {
283+
return diag.FromErr(err)
284+
}
275285

276-
_, err = attachLBPrivateNetworks(ctx, lbAPI, zone, pnConfigs, lb.ID, d.Timeout(schema.TimeoutCreate))
277-
if err != nil {
278-
return diag.FromErr(err)
279-
}
286+
_, err = attachLBPrivateNetworks(ctx, lbAPI, zone, pnConfigs, lb.ID, d.Timeout(schema.TimeoutCreate))
287+
if err != nil {
288+
return diag.FromErr(err)
289+
}
280290

281-
_, err = waitForLB(ctx, lbAPI, zone, lb.ID, d.Timeout(schema.TimeoutCreate))
282-
if err != nil {
283-
return diag.FromErr(err)
291+
_, err = waitForLB(ctx, lbAPI, zone, lb.ID, d.Timeout(schema.TimeoutCreate))
292+
if err != nil {
293+
return diag.FromErr(err)
294+
}
284295
}
285296
}
286297

@@ -352,7 +363,12 @@ func resourceLbRead(ctx context.Context, d *schema.ResourceData, m any) diag.Dia
352363
return diag.FromErr(err)
353364
}
354365

355-
_ = d.Set("private_network", flattenPrivateNetworkConfigs(privateNetworks))
366+
external := d.Get("external_private_networks").(bool)
367+
if !external {
368+
_ = d.Set("private_network", flattenPrivateNetworkConfigs(privateNetworks))
369+
} else {
370+
_ = d.Set("private_network", schema.NewSet(lbPrivateNetworkSetHash, []any{}))
371+
}
356372

357373
privateNetworkIDs := make([]string, 0, len(privateNetworks))
358374
for _, pn := range privateNetworks {
@@ -521,7 +537,8 @@ func resourceLbUpdate(ctx context.Context, d *schema.ResourceData, m any) diag.D
521537
////
522538
// Attach / Detach Private Networks
523539
////
524-
if d.HasChange("private_network") {
540+
external := d.Get("external_private_networks").(bool)
541+
if !external && d.HasChange("private_network") {
525542
// check current lb stability state
526543
_, err = waitForLB(ctx, lbAPI, zone, ID, d.Timeout(schema.TimeoutUpdate))
527544
if err != nil {

0 commit comments

Comments
 (0)