Skip to content

Commit 22a6223

Browse files
authored
feat(vpc): add vpc resource (#1962)
* feat(vpc): add vpc resource * fix * add doc
1 parent e0bb56d commit 22a6223

11 files changed

+1400
-12
lines changed

docs/resources/vpc.md

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
subcategory: "VPC"
3+
page_title: "Scaleway: scaleway_vpc"
4+
---
5+
6+
# scaleway_vpc
7+
8+
Creates and manages Scaleway Virtual Private Clouds.
9+
For more information, see [the documentation](https://www.scaleway.com/en/docs/network/vpc/concepts/).
10+
11+
## Example
12+
13+
```hcl
14+
resource "scaleway_vpc" "vpc01" {
15+
name = "my-vpc"
16+
tags = ["demo", "terraform"]
17+
}
18+
```
19+
20+
## Arguments Reference
21+
22+
The following arguments are supported:
23+
24+
- `name` - (Optional) The name of the VPC. If not provided it will be randomly generated.
25+
- `tags` - (Optional) The tags associated with the VPC.
26+
- `region` - (Defaults to [provider](../index.md#region) `region`) The [region](../guides/regions_and_zones.md#regions) of the VPC.
27+
- `project_id` - (Defaults to [provider](../index.md#project_id) `project_id`) The ID of the project the VPC is associated with.
28+
29+
## Attributes Reference
30+
31+
In addition to all above arguments, the following attributes are exported:
32+
33+
- `id` - The ID of the VPC.
34+
- `is_default` - Defines whether the VPC is the default one for its Project.
35+
- `created_at` - Date and time of VPC's creation (RFC 3339 format).
36+
- `updated_at` - Date and time of VPC's last update (RFC 3339 format).
37+
38+
~> **Important:** VPCs' IDs are [regional](../guides/regions_and_zones.md#resource-ids), which means they are of the form `{region}/{id}`, e.g. `fr-par/11111111-1111-1111-1111-111111111111
39+
40+
- `organization_id` - The organization ID the VPC is associated with.
41+
42+
## Import
43+
44+
VPCs can be imported using the `{region}/{id}`, e.g.
45+
46+
```bash
47+
$ terraform import scaleway_vpc.vpc_demo fr-par/11111111-1111-1111-1111-111111111111
48+
```

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ require (
1515
github.com/hashicorp/terraform-plugin-sdk/v2 v2.26.1
1616
github.com/nats-io/nats.go v1.25.0
1717
github.com/robfig/cron/v3 v3.0.1
18-
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.16.0.20230425114903-9de7ce5b674f
18+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.17.0.20230526161530-cf508019231d
1919
github.com/stretchr/testify v1.8.2
2020
)
2121

go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,8 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
251251
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
252252
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
253253
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
254-
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.16.0.20230425114903-9de7ce5b674f h1:h/skrTv7wKdxr88CjkD2cdVLaWqarBwXRQTE1XCraKg=
255-
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.16.0.20230425114903-9de7ce5b674f/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg=
254+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.17.0.20230526161530-cf508019231d h1:qeI25+qrQ5MQaMFS2RgmAeAwUSWZSeYy5eYHnmW8vpk=
255+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.17.0.20230526161530-cf508019231d/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg=
256256
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
257257
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
258258
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=

scaleway/helpers_vpc.go

+32-7
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ import (
44
"fmt"
55

66
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
7-
"github.com/scaleway/scaleway-sdk-go/api/vpc/v1"
7+
v1 "github.com/scaleway/scaleway-sdk-go/api/vpc/v1"
8+
v2 "github.com/scaleway/scaleway-sdk-go/api/vpc/v2"
89
"github.com/scaleway/scaleway-sdk-go/scw"
910
)
1011

1112
// vpcAPIWithZone returns a new VPC API and the zone for a Create request
12-
func vpcAPIWithZone(d *schema.ResourceData, m interface{}) (*vpc.API, scw.Zone, error) {
13+
func vpcAPIWithZone(d *schema.ResourceData, m interface{}) (*v1.API, scw.Zone, error) {
1314
meta := m.(*Meta)
14-
vpcAPI := vpc.NewAPI(meta.scwClient)
15+
vpcAPI := v1.NewAPI(meta.scwClient)
1516

1617
zone, err := extractZone(d, meta)
1718
if err != nil {
@@ -21,9 +22,9 @@ func vpcAPIWithZone(d *schema.ResourceData, m interface{}) (*vpc.API, scw.Zone,
2122
}
2223

2324
// vpcAPIWithZoneAndID
24-
func vpcAPIWithZoneAndID(m interface{}, id string) (*vpc.API, scw.Zone, string, error) {
25+
func vpcAPIWithZoneAndID(m interface{}, id string) (*v1.API, scw.Zone, string, error) {
2526
meta := m.(*Meta)
26-
vpcAPI := vpc.NewAPI(meta.scwClient)
27+
vpcAPI := v1.NewAPI(meta.scwClient)
2728

2829
zone, ID, err := parseZonedID(id)
2930
if err != nil {
@@ -32,13 +33,37 @@ func vpcAPIWithZoneAndID(m interface{}, id string) (*vpc.API, scw.Zone, string,
3233
return vpcAPI, zone, ID, err
3334
}
3435

35-
func vpcAPI(m interface{}) (*vpc.API, error) {
36+
// vpcAPIWithRegion returns a new VPC API and the region for a Create request
37+
func vpcAPIWithRegion(d *schema.ResourceData, m interface{}) (*v2.API, scw.Region, error) {
38+
meta := m.(*Meta)
39+
vpcAPI := v2.NewAPI(meta.scwClient)
40+
41+
region, err := extractRegion(d, meta)
42+
if err != nil {
43+
return nil, "", err
44+
}
45+
return vpcAPI, region, err
46+
}
47+
48+
// vpcAPIWithRegionAndID
49+
func vpcAPIWithRegionAndID(m interface{}, id string) (*v2.API, scw.Region, string, error) {
50+
meta := m.(*Meta)
51+
vpcAPI := v2.NewAPI(meta.scwClient)
52+
53+
region, ID, err := parseRegionalID(id)
54+
if err != nil {
55+
return nil, "", "", err
56+
}
57+
return vpcAPI, region, ID, err
58+
}
59+
60+
func vpcAPI(m interface{}) (*v1.API, error) {
3661
meta, ok := m.(*Meta)
3762
if !ok {
3863
return nil, fmt.Errorf("wrong type: %T", m)
3964
}
4065

41-
return vpc.NewAPI(meta.scwClient), nil
66+
return v1.NewAPI(meta.scwClient), nil
4267
}
4368

4469
func expandSubnets(data interface{}) ([]scw.IPNet, error) {

scaleway/provider.go

+1
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ func Provider(config *ProviderConfig) plugin.ProviderFunc {
155155
"scaleway_mnq_queue": resourceScalewayMNQQueue(),
156156
"scaleway_secret": resourceScalewaySecret(),
157157
"scaleway_secret_version": resourceScalewaySecretVersion(),
158+
"scaleway_vpc": resourceScalewayVPC(),
158159
"scaleway_vpc_public_gateway": resourceScalewayVPCPublicGateway(),
159160
"scaleway_vpc_gateway_network": resourceScalewayVPCGatewayNetwork(),
160161
"scaleway_vpc_public_gateway_dhcp": resourceScalewayVPCPublicGatewayDHCP(),

scaleway/resource_vpc.go

+148
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
package scaleway
2+
3+
import (
4+
"context"
5+
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
8+
"github.com/scaleway/scaleway-sdk-go/api/vpc/v2"
9+
"github.com/scaleway/scaleway-sdk-go/scw"
10+
)
11+
12+
func resourceScalewayVPC() *schema.Resource {
13+
return &schema.Resource{
14+
CreateContext: resourceScalewayVPCCreate,
15+
ReadContext: resourceScalewayVPCRead,
16+
UpdateContext: resourceScalewayVPCUpdate,
17+
DeleteContext: resourceScalewayVPCDelete,
18+
Importer: &schema.ResourceImporter{
19+
StateContext: schema.ImportStatePassthroughContext,
20+
},
21+
SchemaVersion: 0,
22+
Schema: map[string]*schema.Schema{
23+
"name": {
24+
Type: schema.TypeString,
25+
Optional: true,
26+
Description: "The name of the VPC",
27+
Computed: true,
28+
},
29+
"tags": {
30+
Type: schema.TypeList,
31+
Optional: true,
32+
Description: "The tags associated with the VPC",
33+
Elem: &schema.Schema{
34+
Type: schema.TypeString,
35+
},
36+
},
37+
"project_id": projectIDSchema(),
38+
"region": regionSchema(),
39+
// Computed elements
40+
"organization_id": organizationIDSchema(),
41+
"is_default": {
42+
Type: schema.TypeBool,
43+
Computed: true,
44+
Description: "Defines whether the VPC is the default one for its Project",
45+
},
46+
"created_at": {
47+
Type: schema.TypeString,
48+
Computed: true,
49+
Description: "The date and time of the creation of the private network",
50+
},
51+
"updated_at": {
52+
Type: schema.TypeString,
53+
Computed: true,
54+
Description: "The date and time of the last update of the private network",
55+
},
56+
},
57+
}
58+
}
59+
60+
func resourceScalewayVPCCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
61+
vpcAPI, region, err := vpcAPIWithRegion(d, meta)
62+
if err != nil {
63+
return diag.FromErr(err)
64+
}
65+
66+
res, err := vpcAPI.CreateVPC(&vpc.CreateVPCRequest{
67+
Name: expandOrGenerateString(d.Get("name"), "vpc"),
68+
Tags: expandStrings(d.Get("tags")),
69+
ProjectID: d.Get("project_id").(string),
70+
Region: region,
71+
}, scw.WithContext(ctx))
72+
if err != nil {
73+
return diag.FromErr(err)
74+
}
75+
76+
d.SetId(newRegionalIDString(region, res.ID))
77+
78+
return resourceScalewayVPCRead(ctx, d, meta)
79+
}
80+
81+
func resourceScalewayVPCRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
82+
vpcAPI, region, ID, err := vpcAPIWithRegionAndID(meta, d.Id())
83+
if err != nil {
84+
return diag.FromErr(err)
85+
}
86+
87+
res, err := vpcAPI.GetVPC(&vpc.GetVPCRequest{
88+
Region: region,
89+
VpcID: ID,
90+
}, scw.WithContext(ctx))
91+
if err != nil {
92+
if is404Error(err) {
93+
d.SetId("")
94+
return nil
95+
}
96+
return diag.FromErr(err)
97+
}
98+
99+
_ = d.Set("name", res.Name)
100+
_ = d.Set("organization_id", res.OrganizationID)
101+
_ = d.Set("project_id", res.ProjectID)
102+
_ = d.Set("created_at", flattenTime(res.CreatedAt))
103+
_ = d.Set("updated_at", flattenTime(res.UpdatedAt))
104+
_ = d.Set("is_default", res.IsDefault)
105+
_ = d.Set("region", region)
106+
107+
if len(res.Tags) > 0 {
108+
_ = d.Set("tags", res.Tags)
109+
}
110+
111+
return nil
112+
}
113+
114+
func resourceScalewayVPCUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
115+
vpcAPI, region, ID, err := vpcAPIWithRegionAndID(meta, d.Id())
116+
if err != nil {
117+
return diag.FromErr(err)
118+
}
119+
120+
_, err = vpcAPI.UpdateVPC(&vpc.UpdateVPCRequest{
121+
VpcID: ID,
122+
Region: region,
123+
Name: scw.StringPtr(d.Get("name").(string)),
124+
Tags: expandUpdatedStringsPtr(d.Get("tags")),
125+
}, scw.WithContext(ctx))
126+
if err != nil {
127+
return diag.FromErr(err)
128+
}
129+
130+
return resourceScalewayVPCRead(ctx, d, meta)
131+
}
132+
133+
func resourceScalewayVPCDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
134+
vpcAPI, region, ID, err := vpcAPIWithRegionAndID(meta, d.Id())
135+
if err != nil {
136+
return diag.FromErr(err)
137+
}
138+
139+
err = vpcAPI.DeleteVPC(&vpc.DeleteVPCRequest{
140+
Region: region,
141+
VpcID: ID,
142+
}, scw.WithContext(ctx))
143+
if err != nil {
144+
return diag.FromErr(err)
145+
}
146+
147+
return nil
148+
}

scaleway/resource_vpc_private_network_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import (
1111
)
1212

1313
func init() {
14-
resource.AddTestSweepers("scaleway_vpc", &resource.Sweeper{
15-
Name: "scaleway_vpc",
14+
resource.AddTestSweepers("scaleway_vpc_private_network", &resource.Sweeper{
15+
Name: "scaleway_vpc_private_network",
1616
F: testSweepVPCPrivateNetwork,
1717
})
1818
}

0 commit comments

Comments
 (0)